From 675e7e0171ad317409e4cefc1c4fe23e741b45dd Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 11 Jan 2020 00:04:20 +0000 Subject: [PATCH 01/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 532c36683a..12fc8a0e02 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1715 + FORMAL BUILD NUMBER:1717 */ -#define PRODUCT_VER_STRING "4.0.0.1715" -#define FILE_VER_STRING "WI-T4.0.0.1715" -#define LICENSE_VER_STRING "WI-T4.0.0.1715" -#define FILE_VER_NUMBER 4, 0, 0, 1715 +#define PRODUCT_VER_STRING "4.0.0.1717" +#define FILE_VER_STRING "WI-T4.0.0.1717" +#define LICENSE_VER_STRING "WI-T4.0.0.1717" +#define FILE_VER_NUMBER 4, 0, 0, 1717 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1715" +#define FB_BUILD_NO "1717" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 1f6cbcf0ce..0e0c7eb584 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1715 +BuildNum=1717 NowAt=`pwd` cd `dirname $0` From a9923c92afbfed3d3b41423f5f29b754e00bcc09 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Sun, 12 Jan 2020 10:38:31 +0300 Subject: [PATCH 02/39] Avoid unnecessary operations in the destructor. This also prevents possible hangs in Classic builds. --- src/jrd/Monitoring.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index f5d55d1bbe..7a9986cf9a 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -133,13 +133,20 @@ MonitoringData::MonitoringData(const Database* dbb) MonitoringData::~MonitoringData() { - Guard guard(this); + m_sharedMemory->mutexLock(); - if (m_sharedMemory->getHeader() && - m_sharedMemory->getHeader()->used == alignOffset(sizeof(Header))) + try { - m_sharedMemory->removeMapFile(); + if (m_sharedMemory->getHeader() && + m_sharedMemory->getHeader()->used == alignOffset(sizeof(Header))) + { + m_sharedMemory->removeMapFile(); + } } + catch (const Exception&) + {} // no-op + + m_sharedMemory->mutexUnlock(); } From fb74077793d1e8acd171035b8f99892c1fc25c29 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sun, 12 Jan 2020 13:29:06 -0300 Subject: [PATCH 03/39] Avoid warning of possible usage without initialization. --- src/common/cvt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/cvt.cpp b/src/common/cvt.cpp index ecac568f9f..dfeb2019e2 100644 --- a/src/common/cvt.cpp +++ b/src/common/cvt.cpp @@ -1802,7 +1802,7 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c const UCHAR* start = to->dsc_address; UCHAR fill_char = ASCII_SPACE; Jrd::CharSet* toCharset = cb->getToCharset(charset2); - ULONG toLength; + ULONG toLength = 0; ULONG fill; if (charset2 == ttype_binary) From d0bebcb7893b9ef9cbaef430c89db18521e3b8d7 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Mon, 13 Jan 2020 00:04:51 +0000 Subject: [PATCH 04/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 12fc8a0e02..f160c1f5e4 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1717 + FORMAL BUILD NUMBER:1719 */ -#define PRODUCT_VER_STRING "4.0.0.1717" -#define FILE_VER_STRING "WI-T4.0.0.1717" -#define LICENSE_VER_STRING "WI-T4.0.0.1717" -#define FILE_VER_NUMBER 4, 0, 0, 1717 +#define PRODUCT_VER_STRING "4.0.0.1719" +#define FILE_VER_STRING "WI-T4.0.0.1719" +#define LICENSE_VER_STRING "WI-T4.0.0.1719" +#define FILE_VER_NUMBER 4, 0, 0, 1719 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1717" +#define FB_BUILD_NO "1719" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 0e0c7eb584..d8a847a2d2 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1717 +BuildNum=1719 NowAt=`pwd` cd `dirname $0` From 190262f63410022f261aef380e6c1393a93c3582 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 13 Jan 2020 17:07:26 +0300 Subject: [PATCH 05/39] Disable simultaneous access to read-only database from multiple processes in SS mode --- src/jrd/os/posix/unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jrd/os/posix/unix.cpp b/src/jrd/os/posix/unix.cpp index b1c5ab06fb..3a0794dbae 100644 --- a/src/jrd/os/posix/unix.cpp +++ b/src/jrd/os/posix/unix.cpp @@ -713,7 +713,7 @@ jrd_file* PIO_open(thread_db* tdbb, } const bool shareMode = dbb->dbb_config->getServerMode() != MODE_SUPER; - lockDatabaseFile(desc, shareMode || readOnly, false, file_name.c_str(), isc_io_open_err); + lockDatabaseFile(desc, shareMode, false, file_name.c_str(), isc_io_open_err); // os_utils::posix_fadvise(desc, 0, 0, POSIX_FADV_RANDOM); From fa8d7c984a1fa7f6d32c592ab462775145d86a9e Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 13 Jan 2020 17:08:23 +0300 Subject: [PATCH 06/39] Make firebird engine use classic mode during boot build --- src/common/config/config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/config/config.cpp b/src/common/config/config.cpp index c02df718e1..ddfe804adb 100644 --- a/src/common/config/config.cpp +++ b/src/common/config/config.cpp @@ -202,7 +202,7 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] = {TYPE_STRING, "UserManager", (ConfigValue) "Srp"}, {TYPE_STRING, "TracePlugin", (ConfigValue) "fbtrace"}, {TYPE_STRING, "SecurityDatabase", (ConfigValue) "security.db"}, // sec/db alias - rely on databases.conf - {TYPE_STRING, "ServerMode", (ConfigValue) "Super"}, + {TYPE_STRING, "ServerMode", (ConfigValue) ""}, // actual value differs in boot/regular cases {TYPE_STRING, "WireCrypt", (ConfigValue) NULL}, {TYPE_STRING, "WireCryptPlugin", (ConfigValue) "Arc4"}, {TYPE_STRING, "KeyHolderPlugin", (ConfigValue) ""}, @@ -718,7 +718,7 @@ int Config::getServerMode() } // use default - rc = MODE_SUPER; + rc = fb_utils::bootBuild() ? MODE_CLASSIC : MODE_SUPER; return rc; } From 9d02e7e1e4d1e411edc343fa7185394f08ad964c Mon Sep 17 00:00:00 2001 From: Kovalenko Dmitry Date: Mon, 13 Jan 2020 10:20:06 +0300 Subject: [PATCH 07/39] Correction of RefPtr::assign When RefPtr::assign returns to caller it (object) may be already destroyed. As result "return ptr" will access (read 'ptr' member) the destroyed object. The correct code - 'return p;' Note: usually smart pointers do not return internal/raw pointers. They return reference to himself. --- src/common/classes/RefCounted.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/classes/RefCounted.h b/src/common/classes/RefCounted.h index d8a6027c47..547f1f9171 100644 --- a/src/common/classes/RefCounted.h +++ b/src/common/classes/RefCounted.h @@ -219,7 +219,7 @@ namespace Firebird } } - return ptr; + return p; } private: From 5e962f0e5a363f5ef1e88c22c41d2588abf2d33b Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 13 Jan 2020 20:22:51 +0300 Subject: [PATCH 08/39] Fixed CORE-2251: gbak doesn't return error code --- src/burp/burp.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/burp/burp.cpp b/src/burp/burp.cpp index c8bc046f6e..ed449de7f4 100644 --- a/src/burp/burp.cpp +++ b/src/burp/burp.cpp @@ -826,16 +826,14 @@ int gbak(Firebird::UtilSvc* uSvc) FILE* tmp_outfile = os_utils::fopen(redirect, fopen_read_type); if (tmp_outfile) { - BURP_print(true, 66, redirect); - // msg 66 can't open status and error output file %s fclose(tmp_outfile); - BURP_exit_local(FINI_ERROR, tdgbl); + BURP_error(66, true, SafeArg() << redirect); + // msg 66 can't open status and error output file %s } if (! (tdgbl->output_file = os_utils::fopen(redirect, fopen_write_type))) { - BURP_print(true, 66, redirect); + BURP_error(66, true, SafeArg() << redirect); // msg 66 can't open status and error output file %s - BURP_exit_local(FINI_ERROR, tdgbl); } } } From 96c59e65408395561a2dda947afdac39d6c16cd0 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 14 Jan 2020 00:04:36 +0000 Subject: [PATCH 09/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index f160c1f5e4..f9937727b1 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1719 + FORMAL BUILD NUMBER:1723 */ -#define PRODUCT_VER_STRING "4.0.0.1719" -#define FILE_VER_STRING "WI-T4.0.0.1719" -#define LICENSE_VER_STRING "WI-T4.0.0.1719" -#define FILE_VER_NUMBER 4, 0, 0, 1719 +#define PRODUCT_VER_STRING "4.0.0.1723" +#define FILE_VER_STRING "WI-T4.0.0.1723" +#define LICENSE_VER_STRING "WI-T4.0.0.1723" +#define FILE_VER_NUMBER 4, 0, 0, 1723 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1719" +#define FB_BUILD_NO "1723" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index d8a847a2d2..73bb6e26c3 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1719 +BuildNum=1723 NowAt=`pwd` cd `dirname $0` From c6523020b15eebdcb9eef47d04ade8594eaa8439 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Tue, 14 Jan 2020 17:10:48 +0300 Subject: [PATCH 10/39] Fixed CORE-6227: isc_info_svc_user_dbpath always returns alias of main security database --- src/jrd/svc.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/jrd/svc.cpp b/src/jrd/svc.cpp index f31d051e0e..e1861ad296 100644 --- a/src/jrd/svc.cpp +++ b/src/jrd/svc.cpp @@ -1365,11 +1365,13 @@ ISC_STATUS Service::query2(thread_db* /*tdbb*/, case isc_info_svc_user_dbpath: if (svc_user_flag & SVC_user_dba) { - // The path to the user security database (security2.fdb) - const RefPtr defConf(Config::getDefaultConfig()); - const char* secDb = defConf->getSecurityDatabase(); + // The path to the user security database + PathName secDb; + RefPtr config; + expandDatabaseName(svc_expected_db, secDb, &config); + expandDatabaseName(config->getSecurityDatabase(), secDb, nullptr); - if (!(info = INF_put_item(item, static_cast(strlen(secDb)), secDb, info, end))) + if (!(info = INF_put_item(item, static_cast(secDb.length()), secDb.c_str(), info, end))) { return 0; } @@ -1817,11 +1819,13 @@ void Service::query(USHORT send_item_length, case isc_info_svc_user_dbpath: if (svc_user_flag & SVC_user_dba) { - // The path to the user security database (security2.fdb) - const RefPtr defConf(Config::getDefaultConfig()); - const char* secDb = defConf->getSecurityDatabase(); + // The path to the user security database + PathName secDb; + RefPtr config; + expandDatabaseName(svc_expected_db, secDb, &config); + expandDatabaseName(config->getSecurityDatabase(), secDb, nullptr); - if (!(info = INF_put_item(item, static_cast(strlen(secDb)), secDb, info, end))) + if (!(info = INF_put_item(item, static_cast(secDb.length()), secDb.c_str(), info, end))) { return; } From 64ecbd8dd2026baf6954c3ce09e77bbf85613a9e Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 14 Jan 2020 12:40:25 -0300 Subject: [PATCH 11/39] CORE-6214 - Update outdated tzdata version. Added documentation and script for update. zipjs.bat is downloaded from https://github.com/npocmaka/batch.scripts/blob/master/hybrids/jscript/zipjs.bat --- builds/posix/Makefile.in | 10 +- builds/win32/make_all.bat | 2 + builds/win32/make_icu.bat | 8 +- builds/win32/zipjs.bat | 823 +++++++++++++++++++++++++ doc/sql.extensions/README.time_zone.md | 12 +- src/common/TimeZoneUtil.cpp | 16 + src/common/TimeZoneUtil.h | 6 + src/common/unicode_util.cpp | 13 + src/common/utils.cpp | 30 + src/common/utils_proto.h | 1 + src/yvalve/why.cpp | 14 + tzdata/be.zip | Bin 0 -> 91876 bytes tzdata/le.zip | Bin 0 -> 91147 bytes tzdata/update.sh | 32 + tzdata/version.txt | 1 + 15 files changed, 959 insertions(+), 9 deletions(-) create mode 100644 builds/win32/zipjs.bat create mode 100644 tzdata/be.zip create mode 100644 tzdata/le.zip create mode 100755 tzdata/update.sh create mode 100644 tzdata/version.txt diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index 538c3fb714..c16801ea95 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -630,13 +630,13 @@ $(IDS): $(SRC_ROOT)/misc/ids.m $(SRC_ROOT)/jrd/relations.h # all the rest we need to build # -.PHONY: qli message_file gbak_files +.PHONY: qli message_file tzdata gbak_files FDB_FILES := $(HELP_FDB) $(ROOT)/gen/msg.fdb $(SECURITY_FDB) $(FIREBIRD)/examples/empbuild/employee.fdb GBAK_FILES := $(FDB_FILES:.fdb=.gbak) $(FIREBIRD)/msg.gbak GBAK_FILES := $(subst Native,$(TARGET),$(GBAK_FILES)) -rest: qli message_file +rest: qli message_file tzdata cross_rest: qli gbak_files $(MAKE) $(BUILD_FILE) @@ -656,6 +656,12 @@ $(FIREBIRD_MSG): $(BUILD_FILE) msg.timestamp $(BUILD_FILE) -d msg.fdb -f $@ $(CHMOD_6) $@ +tzdata: $(FIREBIRD)/tzdata + +# FIXME: For big-endian, be.zip must be used. +$(FIREBIRD)/tzdata: $(ROOT)/tzdata/le.zip + unzip -o $(ROOT)/tzdata/le.zip -d $(FIREBIRD)/tzdata + $(BUILD_FILE): $(BUILD_Objects) $(COMMON_LIB) $(EXE_LINK) $(EXE_LINK_OPTIONS) $(LSB_UNDEF) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,..) diff --git a/builds/win32/make_all.bat b/builds/win32/make_all.bat index b10caa714c..d1f6ec1b7f 100644 --- a/builds/win32/make_all.bat +++ b/builds/win32/make_all.bat @@ -38,6 +38,7 @@ if errorlevel 1 call :ERROR build failed - see make_all_%FB_TARGET_PLATFORM%.log @mkdir %FB_OUTPUT_DIR% 2>nul @mkdir %FB_OUTPUT_DIR%\intl 2>nul +@mkdir %FB_OUTPUT_DIR%\tzdata 2>nul @mkdir %FB_OUTPUT_DIR%\help 2>nul @mkdir %FB_OUTPUT_DIR%\doc 2>nul @mkdir %FB_OUTPUT_DIR%\doc\sql.extensions 2>nul @@ -50,6 +51,7 @@ if errorlevel 1 call :ERROR build failed - see make_all_%FB_TARGET_PLATFORM%.log @copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\* %FB_OUTPUT_DIR% >nul @copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\intl\* %FB_OUTPUT_DIR%\intl >nul +@copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata\* %FB_OUTPUT_DIR%\tzdata >nul @copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\system32\* %FB_OUTPUT_DIR%\system32 >nul @copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\plugins\*.dll %FB_OUTPUT_DIR%\plugins >nul @copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\plugins\udr\*.dll %FB_OUTPUT_DIR%\plugins\udr >nul diff --git a/builds/win32/make_icu.bat b/builds/win32/make_icu.bat index 3f14be2659..7eaa3aaf0a 100644 --- a/builds/win32/make_icu.bat +++ b/builds/win32/make_icu.bat @@ -10,12 +10,14 @@ :: MAIN @echo Extracting pre-built ICU - %FB_ROOT_PATH%\extern\icu\icu.exe -y > make_icu_%FB_TARGET_PLATFORM%.log 2>&1 - if errorlevel 1 call :ERROR build failed - see make_icu_%FB_TARGET_PLATFORM%.log for details -@goto :EOF +@echo Extracting tzdata +mkdir %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata +call zipjs.bat unzip -source "%FB_LONG_ROOT_PATH%\tzdata\le.zip" -destination %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata -keep yes + +@goto :EOF :ERROR diff --git a/builds/win32/zipjs.bat b/builds/win32/zipjs.bat new file mode 100644 index 0000000000..02b8fcbc24 --- /dev/null +++ b/builds/win32/zipjs.bat @@ -0,0 +1,823 @@ +@if (@X)==(@Y) @end /* JScript comment + @echo off + + rem :: the first argument is the script name as it will be used for proper help message + cscript //E:JScript //nologo "%~f0" "%~nx0" %* + + exit /b %errorlevel% + +@if (@X)==(@Y) @end JScript comment */ + + +/* +Compression/uncompression command-line tool that uses Shell.Application and WSH/Jscript - +http://msdn.microsoft.com/en-us/library/windows/desktop/bb774085(v=vs.85).aspx + +Some resources That I've used: +http://www.robvanderwoude.com/vbstech_files_zip.php +https://code.google.com/p/jsxt/source/browse/trunk/js/win32/ZipFile.js?r=161 + + + + +UPDATE *17-03-15* + +Devnullius Plussed noticed a bug in ZipDirItems and ZipItem functions (now fixed) +And also following issues (at the moment not handled by the script): +- if there's not enough space on the system drive (usually C:\) the script could produce various errors , most often the script halts. +- Folders and files that contain unicode symbols cannot be handled by Shell.Application object. + +UPDATE *24-03-15* + +Error messages are caught in waitforcount method and if shuch pops-up the script is stopped. +As I don't know hoe to check the content of the pop-up the exact reason for the failure is not given +but only the possible reasons. + +UPDATE *22-02-16* + +Javid Pack(https://github.com/JavidPack) has found two bugs in zipItem command and in ZipItem function.Now fixed. + +------ +It's possible to be ported for C#,Powershell and JScript.net so I'm planning to do it at some time. + +For sure there's a lot of room for improvements and optimization and I'm absolutely sure there are some bugs +as the script is big enough to not have. + + + +!!! +For suggestions contact me at - npocmaka@gmail.com +!!! + +*/ + + +////////////////////////////////////// +// CONSTANTS + +// TODO - Shell.Application and Scripting.FileSystemObject objects could be set as global variables to avoid theit creation +// in every method. + +//empty zip character sequense +var ZIP_DATA= "PK" + String.fromCharCode(5) + String.fromCharCode(6) + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + +var SLEEP_INTERVAL=200; + +//copy option(s) used by Shell.Application.CopyHere/MoveHere +var NO_PROGRESS_BAR=4; + + +//oprions used for zip/unzip +var force=true; +var move=false; + +//option used for listing content of archive +var flat=false; + +var source=""; +var destination=""; + +var ARGS = WScript.Arguments; +var scriptName=ARGS.Item(0); + +// +////////////////////////////////////// + +////////////////////////////////////// +// ADODB.Stream extensions + +if ( ! this.ADODB ) { + var ADODB = {}; +} + +if ( ! ADODB.Stream ) { + ADODB.Stream = {}; +} + +// writes a binary data to a file +if ( ! ADODB.Stream.writeFile ) { + ADODB.Stream.writeFile = function(filename, bindata) + { + var stream = new ActiveXObject("ADODB.Stream"); + stream.Type = 2; + stream.Mode = 3; + stream.Charset ="ASCII"; + stream.Open(); + stream.Position = 0; + stream.WriteText(bindata); + stream.SaveToFile(filename, 2); + stream.Close(); + return true; + }; +} + +// +////////////////////////////////////// + +////////////////////////////////////// +// common + +if ( ! this.Common ) { + var Common = {}; +} + +if ( ! Common.WaitForCount ) { + Common.WaitForCount = function(folderObject,targetCount,countFunction){ + var shell = new ActiveXObject("Wscript.Shell"); + while (countFunction(folderObject) < targetCount ){ + WScript.Sleep(SLEEP_INTERVAL); + //checks if a pop-up with error message appears while zipping + //at the moment I have no idea how to read the pop-up content + // to give the exact reason for failing + if (shell.AppActivate("Compressed (zipped) Folders Error")) { + WScript.Echo("Error While zipping"); + WScript.Echo(""); + WScript.Echo("Possible reasons:"); + WScript.Echo(" -source contains filename(s) with unicode characters"); + WScript.Echo(" -produces zip exceeds 8gb size (or 2,5 gb for XP and 2003)"); + WScript.Echo(" -not enough space on system drive (usually C:\\)"); + WScript.Quit(432); + } + + } + } +} + +if ( ! Common.getParent ) { + Common.getParent = function(path){ + var splitted=path.split("\\"); + var result=""; + for (var s=0;s/tzdata` is the default directory where Firebird looks for the database. It could be overriden with the `ICU_TIMEZONE_FILES_DIR` environment variable. + +Important note: Firebird stores `WITH TIME ZONE` values translated to UTC time. If a value is created with one time zone database and later that database is updated and the update changes the information in the range of a stored value, when reading that value it will be returned as a different value than the one initially stored. # Appendix: time zone regions diff --git a/src/common/TimeZoneUtil.cpp b/src/common/TimeZoneUtil.cpp index 05d1d6f7ee..862686466c 100644 --- a/src/common/TimeZoneUtil.cpp +++ b/src/common/TimeZoneUtil.cpp @@ -34,6 +34,7 @@ #include "../common/classes/timestamp.h" #include "../common/classes/GenericMap.h" #include "../common/config/config.h" +#include "../common/os/path_utils.h" #include "unicode/ucal.h" #ifdef TZ_UPDATE @@ -190,6 +191,21 @@ static InitInstance timeZoneStartup; //------------------------------------- const char TimeZoneUtil::GMT_FALLBACK[5] = "GMT*"; +InitInstance TimeZoneUtil::tzDataPath; + +void TimeZoneUtil::initTimeZoneEnv() +{ + PathName path; + PathUtils::concatPath(path, Config::getRootDirectory(), "tzdata"); + + if (fb_utils::setenv("ICU_TIMEZONE_FILES_DIR", path.c_str(), false)) + tzDataPath() = path; +} + +const PathName& TimeZoneUtil::getTzDataPath() +{ + return tzDataPath(); +} // Return the current user's time zone. USHORT TimeZoneUtil::getSystemTimeZone() diff --git a/src/common/TimeZoneUtil.h b/src/common/TimeZoneUtil.h index 69bc5ba18a..b2bda3dd63 100644 --- a/src/common/TimeZoneUtil.h +++ b/src/common/TimeZoneUtil.h @@ -65,6 +65,9 @@ public: static const unsigned MAX_LEN = 32; static const unsigned MAX_SIZE = MAX_LEN + 1; +private: + static InitInstance tzDataPath; + public: static UDate ticksToIcuDate(SINT64 ticks) { @@ -76,6 +79,9 @@ public: return (SINT64(icuDate) * 10) + (TimeStamp::UNIX_DATE * TimeStamp::ISC_TICKS_PER_DAY); } + static void initTimeZoneEnv(); + static const PathName& getTzDataPath(); + static USHORT getSystemTimeZone(); static void getDatabaseVersion(Firebird::string& str); diff --git a/src/common/unicode_util.cpp b/src/common/unicode_util.cpp index faacf19c78..d53dcb50ad 100644 --- a/src/common/unicode_util.cpp +++ b/src/common/unicode_util.cpp @@ -31,12 +31,14 @@ #include "../common/isc_proto.h" #include "../common/CharSet.h" #include "../common/IntlUtil.h" +#include "../common/TimeZoneUtil.h" #include "../common/gdsassert.h" #include "../common/classes/auto.h" #include "../common/classes/GenericMap.h" #include "../common/classes/init.h" #include "../common/classes/objects_array.h" #include "../common/classes/rwlock.h" +#include "../common/config/config.h" #include "../common/StatusHolder.h" #include "../common/os/path_utils.h" @@ -126,9 +128,11 @@ public: void BaseICU::initialize(ModuleLoader::Module* module) { void (U_EXPORT2 *uInit)(UErrorCode* status); + void (U_EXPORT2 *uSetTimeZoneFilesDirectory)(const char* path, UErrorCode* status); void (U_EXPORT2 *uSetDataDirectory)(const char* directory); getEntryPoint("u_init", module, uInit, true); + getEntryPoint("u_setTimeZoneFilesDirectory", module, uSetTimeZoneFilesDirectory, true); getEntryPoint("u_setDataDirectory", module, uSetDataDirectory, true); #if defined(WIN_NT) || defined(DARWIN) @@ -166,6 +170,15 @@ void BaseICU::initialize(ModuleLoader::Module* module) (Arg::Gds(isc_random) << diag).raise(); } } + + // ICU's u_setTimeZoneFilesDirectory is an internal API, but we try to use + // it because internally set ICU_TIMEZONE_FILES_DIR envvar in Windows is not + // safe. See comments in fb_utils::setenv. + if (uSetTimeZoneFilesDirectory && TimeZoneUtil::getTzDataPath().hasData()) + { + UErrorCode status = U_ZERO_ERROR; + uSetTimeZoneFilesDirectory(TimeZoneUtil::getTzDataPath().c_str(), &status); + } } } diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 7ae7234641..09285a6e10 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -38,6 +38,7 @@ #endif #include #include +#include #include #include "../common/gdsassert.h" @@ -303,6 +304,35 @@ bool readenv(const char* env_name, Firebird::PathName& env_value) } +bool setenv(const char* name, const char* value, bool overwrite) +{ +#ifdef WIN_NT + int errcode = 0; + + if (!overwrite) + { + size_t envsize = 0; + errcode = getenv_s(&envsize, NULL, 0, name); + if (errcode || envsize) + return false; + } + + // In Windows, _putenv_s sets only the environment data in the CRT. + // Each DLL (for example ICU) may use a different CRT which different data + // or use Win32's GetEnvironmentVariable, so we also use SetEnvironmentVariable. + // This is a mess and is not guarenteed to work correctly in all situations. + if (SetEnvironmentVariable(name, value)) + { + _putenv_s(name, value); + return true; + } + else + return false; +#else + return ::setenv(name, value, (int) overwrite) == 0; +#endif +} + // *************** // s n p r i n t f // *************** diff --git a/src/common/utils_proto.h b/src/common/utils_proto.h index fa362bec68..f49b7ff1bf 100644 --- a/src/common/utils_proto.h +++ b/src/common/utils_proto.h @@ -55,6 +55,7 @@ namespace fb_utils int name_length_limit(const TEXT* const name, size_t bufsize); bool readenv(const char* env_name, Firebird::string& env_value); bool readenv(const char* env_name, Firebird::PathName& env_value); + bool setenv(const char* name, const char* value, bool overwrite); int snprintf(char* buffer, size_t count, const char* format...); char* cleanup_passwd(char* arg); inline char* get_passwd(char* arg) diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index 1df43ca04b..1fc9754034 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -40,6 +40,7 @@ #include "../common/StatementMetadata.h" #include "../common/StatusHolder.h" #include "../common/ThreadStart.h" +#include "../common/TimeZoneUtil.h" #include "../common/isc_proto.h" #include "../common/isc_f_proto.h" #include "../common/utils_proto.h" @@ -737,6 +738,19 @@ RefPtr translateHandle(GlobalPtr //------------------------------------- +class TimeZoneDataInit +{ +public: + explicit TimeZoneDataInit(MemoryPool&) + { + TimeZoneUtil::initTimeZoneEnv(); + } +}; + +static GlobalPtr timeZoneDataInit; + +//------------------------------------- + const int SHUTDOWN_TIMEOUT = 5000; // 5 sec class ShutdownInit diff --git a/tzdata/be.zip b/tzdata/be.zip new file mode 100644 index 0000000000000000000000000000000000000000..410ebd0605b21684d7dbc5fdb5e33bc3dc19f4a1 GIT binary patch literal 91876 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�q~d_(@Ib00*jY{n(S_1X>j5zg)b7*l9is7lEJ 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 X|2IrD^#80D>T^~@dhTWVY=Hj(dk`44 literal 0 HcmV?d00001 diff --git a/tzdata/le.zip b/tzdata/le.zip new file mode 100644 index 0000000000000000000000000000000000000000..7e9390b15c8eed41502fa3404c0fe6299e258c45 GIT binary patch literal 91147 zcmafaQ*fq1|7B(}@x->RiEZ1qZ6|MR+qP{_Y}>Z^#@YG4-P)@E&F)3_Mb}f^r+&|= zuG6Rc$V-9#LID8*fdm0Hr<6y<&b|TR1_41R00Dso!2z)`aW>Gjvo&#|b2M>MQHBBm z1(!wF{ZDgohXMKV>l73O=9J?Fr{l16F_niO_uos#Of4pj!_sTn1e>+xSQnc0 zo@Y@og*wPYB4_^o9_N;|6N!64j|_nMer&=u4-49x6@s}l8!z+dE6jVZ@2i>V_dAmp z%GAq@`R5tF`peBj?Irzp*v|JW`S908?dSIwQ0^4;viG}x)gPb917W8E4Ho-Iv#$61 zQ*Z6mTklqrm9}0&Y z4USs5WHkc9uzHzPD#+6(m21%*jYKD7}UoOX?$&9oEdm>xd~n_KA_+05IK0_X9O?EAJ6E!b)`v z0QsA>wm+;o!xag+>NDzRniQCzWnVb9m-I!IEl^xzHY^|iQ z&xmbP*@0j-%JWDx>r<<~(IwaBUr+2O7)3#xA9t%j7c+U$JQo` z>uHEgGeWZsIGf0z7CNHc)}r#wr9s~tZ8N4ye-rD>%{eX+YwlCD=R;g1o(cz;i|fQO zae@H71e)mJ3??GqNp_2nMJAJ5^l^b9@B`9(xYt8N-4Ys}JkHmXtkv1RR<%ef zdO^kQU#x3^PC8VrjV<$cj7u9I1nW=A#~Q_4{k14xaWk0`NdB(av4B@|^DsT~jdsPysN0<+k2*2|+9K9IYi zn*rDXcWUGOH^mp0O#Ab{a{Xn5D|-UCkF<*SOzC%sviJ9|QO7|JkoQ&-rSr*u#?ep~?yhKVC{0gHWsTeTbA_}PCLL=D#Smm0&Y$FwzrIWi zA7b>=<0@8=x1IYZL`8di zs_2BYEgU+&r{HOuv{`}nlcLeN_OK$tMwd8eVpHGpjz4L}FVV3^sT3BpWcH$jj~KX? z%ee1`VQ{$<1;BlAwiCBZlu=0KRH|9BCa!!i_~b@S#G7|o^PBjk*gmGjT#_Htx} zhpbZK<~-i)hhJyHI;Eh_<-Q8JN2?X(zuC|wmZjrNP|s~(iRLLgls1~swf#^e&4!US z29=PLxX+M>Gw{rM3JRNkMFN(gUY5#~90KDLZ5&7~v-HAOElD>hI+2(_R=99{$_-YK zR8rYR@%`1}mvWWeJTJk$FvXmbGmIFrfIAMC7DEpPD5aJw1&?yZOIeR~h})}yEdKo5 zoyO{mf7zF142knpaokx>7w>ZO{C=IeH*DDTt=xP7g}-phf_W(xA5@|w^j`h9te)O6 z!|p{E-yf!_{fVZssmLpSH;fcdzhsC zvFN2hdXYhWo6kiA`WUP=B&mfz7z0C+rW~&RkaSROJ-@9P5Uq%5Y#BND%krvNrWoGa z$x9|01g$iICe)fOSsc7?hVIJmM2buNrvelYq)(YDXx@1j?s#>zRVU#+rJEouLDqZ5 zhzXsC-jW9*>QklU^NJ$gUJCn6Ld+pSo+*_(RiV0AHMr_Xygrq#_VOBxyr3{>Hp`E! z1ROeeeDOW+EYl$y(bD~%ln$0B-o7RixAy2rH=rMd(Y#*UYq4DBk1mCq%qIqq#<>;p zOfv=4F+Wjt1nC?@mQinG2};v3V$t(i`lD?z?GEGa_DX8Rz&i?iE2Qu?IjK0Yxw7%5 zaJ(b%^J~s@{HLGCy+RhW6@+ETp_=?9X6ayyAuqmu>ycR!EjOGav<-c*^Q)B^5GGop z)GM?U8@dmOeRLuU!YeY+lg1lxe(hsN`gv9I5WJ`J3)+vXZ&E$2*f?>VB24uo@)RAh z4sBI`pp5t%z@~Sd#|}d!G3M`( z$u>PL-5;oFDDB#0-M7&5Vs)kx+XqjmFo8tzWYy+09rTy|xcg)l|3a>-g-0UM!$=~d zY}#Myt05_>j9RmW;)NnnooJ8#)IAK)yS#)M)TLmyIn<>P%JtOKM3z9H zu-fErJ3=eIh1R+n?cv!|vDMV7P6!eYElJSQzUaRC#O7XtQPa;SYaRJ50j4ukMoGV&aH zj}>BLVm;2R*iGM$nc*|(1n;{AG5olvbCootpg9RttQns^7 z!>Ybgq`ZQThVDS0;B14n*XpFsI+EGCOA=-Mos0T#PrXgtxZ+Zqmrn%;YW$!gw~6D! z8I+slie73D`9cHwKCAJfeV^;~EUfRRaM1Rknm-m~kUDV49^OK^!{r6;_Tp4)PGxq& zNO^CVa}~7h&f$HWVqDChNozwYf5f(JmMR{-jZQrK_dP|&eV`JqN&y5O?QY#03n=p~u>(F-__rTQ_>ci@=HaLvkE zug=B}>$gkC=w>7!uFdmU>)k3e(?Q-1o6VbU_jNn-ZMP+gCA9W zqj7yq9O}2aB>fIca^2G*5#8%FQgE>bd0;@|57U&N`oxyg|xTgqgn)azWcw`b4Ze+(+m}VA%+Y zIeiBAmO7&fTdC+_RDy%1+=D@WksIrWa&o^Z`@f$(^+NQ(RLO(I@;+q0#stuY_RFUr z8WrW3s7N7eKUGz9O9p-gfF?np_uh4*ZBY2%F1gKt4Q&73)NX^9fA%JG{Amq2{Ipt> zhdw1Bn5Lq#i)7u%gMy|onEvzCMH3w@9?vgA3iF1tuX6CN*CVHg!Z0w^b=S|(Q{xPo>2Yn zFz)=LUBD)PTP5izG%BF{wez!T*Pqfdo!EnsD70GoxUn`*o~Hj(B|_v~zHyI8EgfWb zX>|LT=TG8tC`I%^7n4cvm&jeDZ=Pl1T{_q|KNU&Amxb^^VKz+r`@X}P)Gw-xx+F5V znD>{?ig9692*kpM{(H7(xq#IfJ%I$9>Ef7@{E(keAkzZt(f5mE4q;_Vw1LjXh z4+t>DrfC0(gxb|~-tOiyE8+qf?LHWK5hCU1trdlVfex?2@0k(fX)-BS9)n1&7I%{g zwwCeLg)p9OhT#(HKE{t2^=W40APm)dw_Jv|B9ftIL3mr&iTCG+Z8El{&dR9~sb zDha(t+{8tePexbx!&B4j1v?4v6pWdD z)OF0MUUEPXBFDQcT6EqCM!B!4w5rs(m6?S(Pk*!lL2?}Dxdy-OR+mvjZ-}fwM}G23 z+CYts0INOs&=y5*kopey+zaZIolX6G%Ev;irH#daWNp1C=vIvB#XJ5Vu`6!N>ay7{ z=X;!9tyUu06ldlJonEq=^{)tSZ7%xcCQZC5rrRLG3rw$)((1(opP-$HKUPN9G%edn z#-XvM_(IXXmbT@0LhIbi;%VrDy1qR+N zH?Ep@r~DZ>WSGSzw02-TTwcPAajj1)^89Dt&G$Y*ji8qnsy)?>|amo zsZT^QUzd>+_Om*hr)R%P@Rl378a%+MxuUk`w0|zER~4eVh3Dp2(D|Q4M?TM{g8JZe;;`3=kVQY;KPXc;O?WomKM{<-DS{Rns252=tU@IGhA+Sn%}%m zm&|%$E?mN&xy?a@tE(8<*-H!<#$ErG?W8L;J5K7}H`e89AOpu8p8snoTjiF)#bUz6 z*9W`K;XyQnf431&9+Bt*Mer5XLFOvoG~GKFa}JzD@cp}hI%FTl7veIcRPEY=7F4?l zWya%C#C^j=vi@-1R?M^U17@E=maCI@!cE4joIP@Vd1@ugT$d8~E1Nrq(&==YQqs3j zX^YYLZ4x)zHPsrs6S=%-E5}lCTh%Q7>7#@1VJ&D?E#6Jm20Q-d1#AlTO5Q`Daj@2b z0mG7UyyHILIM|SI`rb`gCDb)N)sif!e7%}^Nt>f)5#1HEG_i(b!MF*zcmZd#{mN!_ zF6<iy+yr=ZeVK)+WNX>b$-A&Rnp9H~nekqi@@$+#s*&H%k#o&=E$i&UC@0Ec z&o2$b2~|TeU~Otm0rMWUYt~s^i?tq^;U4gt#hYi=%ekyRd8V_`v&@4m7c=YU0M3>l zgya6)x{9hRn_ZdcUw@xgPtP;jaQsQS#CGO79x=Y|& zAlEg{^(XcIXio9F)8QierbjdlvG%O|Ce23sj$ zt-Xq4#t(PM$;}YP%_SNCAq$p0+L-QC_1c&j{n`8AdHr=7pDQ;R{kdmHf-Eb(v?EsD z|2KyaB8(dPai`1O9Qw;xj+R&Jn^Ow|-S_lJmXhvEhHcpc%iDARTh+CA=W|016kBh; zt;8K?+xr5?z?pp{_masV>XHO310l9k!(mc-jWz&l9)3o9!Yo^Bz+!raVgY{IYyjGQ z53m%s@~Gjnz9Fx7m;Er6_5A(}f3JynaD;9drP4N|z1~XN%tv?1$eGISu*fkW(QuD6 z(K9=aWtgC}g{@)8WbY+lrrl-T?IP5D9$Dq%d5u2i;jWAP=mwL#*xgN+;(N3%9s zp;}KnQcqcuBX2~2al@R%jOJn6MZ8}@RcN1nFd z=R%zzxR2t>w0~LD`D#=*lI^rSt|4={{u1YJ7^2O)(S#ytgmT49_CGn8PSic+J?BKQ zj=KgrH$pz__5J2B<1*zTUe|VkT9>X(er-R=gUh;6McNv-0ya9P@3LC%PKEv?6TI%j}1NWS_tO09BKki#f z0YBPa1JF{NI&mo3p5QggE^wt9p*9A0y5*n(UDD8R?T)wsthrF39+Qr>wZb@fd(V}k z=jGh!So;r28RanuUSi@p!7=%8qD`zE@Qu;D^TkiWB0)#kR?LpeB3y30SkzmemWz(V z1FA()Q^l8FW~Lh<8g}S{Vcv=?z{{cZh^wWt_oR_sI`~M!>rIg3!XNX|K68>?RckZLh3LWf! zlC3hXKre_9HUunI&SOO=Qi#v?vAOd7dev@m)UWZIZ!g}==32A0zj4>U2&c75Q@#?R zCY}isH7cV6Y0&Chc$Z=G0pKqkveT`d4#zVnX6PF0xO4ZdVJAkQ%aaG!t!~|iE~J-f zPe$7-A>`tpfN$C7owF=fhMTcZd(GKkX2#EGLvE~nMybh{-w5VzM&NZ?lPE`sBb)E z%X3apZIuXp)@t&srv&p@Au73Rcd^VBAfcTa;=qkg;KrgYuk1)}rZ39DfGDuQ2{Q$> zm^)JwD5gjsB-jQYV==9ZWn2VnI7$|_Gb`>sYhe-{-KLsGO9$U@bvq^)3$$cIV_Plq zLvE2F5K#&Y;yRDETtB9oLg0GVTGw-TDqxB7VcdjmR%DR%?nMG)SXk8T%>LP; zQP|FYkJ)NHccn0m9R5RAfbDoDK+)rf*^fHthgCAa`!r-1ZKJ9R%?!pdSIYC{UerZ{ z*crk6x_Ig&hCx>SEQcD|88(}+B@T|vGDW&+Kbc9A1Quj|YLY7o%RZ|V!c@xh5QPJ+ za6h7)3wv621O?c-og@D$lVg@wAon;4L@N#FXyKnQ=9q%W3))TUD|5;b7xJLlNE(;Y zosy!{zXbCM$NSK@7W>cW=`ko4&b#Jwy9fxfSL7@RhDj2dI1W-yQK@YK181-nHZ4b! zf%{n9kdSNG%3)2!Lh()*Ufbw}qYpiJ|NaD|M~)Q7vE(NpbKbqBsy&E!o|JhzuE8;2 zvWuCki?F)BKFM@CDc25Im`(ajWG297$alVB4sIgVgaTWgvRix!e0 z(=;RuA4%}#-^?0ZV&w=^Sly?LBa(J)zFJikr4ya23YN+W+7o_qlw6Hx`$CR!RB+5hMbUF z6w~bjx--SqDq%idP!)xR341IO!jomCXy-?B%j+Q zB6>#)SJQtiMB3lyEn#hx`Z(%sW?>{NlL1)3`uFl z@ScJy$lB;x7cSF(A9LABMw2rO;rBvO6#Hf;k0)fjKv^ZpNrl2J;eotb^!;@RlUz=b z&I}7BQ@(U)w-U13RM0^+^$}`a78n=pTF7V<-?6sZFzt-1Xqq&&T)N^0?>_gt^Ta?4 z9|Q5ky}e-AZ&h973Iq$-JnKV&az4m@}N5A>}*cL{R|8eg2Bt$1*wR(Pm$y_WTN75qn||A7$VEs;}PpnM77kI z!f$c+b%ej*yii_^tCl#2kjx^TUVX4D?Jhrml(H$^8B6t0GKHOZ*r?*7R*s*aoP1lV zpjBq#?x{F;Fxji#u>_P3a&n^S-!S%5Nvv|z+s49LKB;Og(Q}5WRvGIzLr&uo*OQlN zsg0YlTlUzBX**=(ZM>r0@g+NmqNNw|hB{o6v&De!ZMr0gS*RX+uMH=_aoNnh^)UG~ ziL)QR`73aLUJX2m={#L%Z*rKtcMo*MXt{yUSn7K*{Zo@QR}?v#rWGq0At`@trC`nF z&W|z`s0Jk-H+V0qG})k6?>V`{P4Nl?C&&i)GL?88c~BdYqZ@Gje`JsmsGNMAvnebx_sn_FvOQLYp_A zJHx7a*1ZXQUV)nq(D1@0K06#M_-PBhi~L^bqjAmN8Dj%a8*$kKY+0!sPP9UEzFhWQ zSC*lgKD@|;;yv1{7E%n*)LDj+X_k7vX@u5fGPvTg$N6+4OY6a2mL& z8Nq$o{3-s;2HEbNE?&dgQ?P_=7vk^ix?K3)K}XK|GSs)_mDV`BNEQQJEpJ(o9@^wH zsiGb#U7ACq4ZmGAcQX4fWRFYqd)8MnQIMRF0LqbbP^>sYbnB|f)vbVG7wixH?~dDADIsDgHX<`a!Vy6Xis z9>-0|Hw%x_sHP6hVI8C(*_IuwcJwe|i)f)V-j)er9M!rEYkJ6zb*(bGTAIeDG170& zXEpQGsqJI4aUYO%FSP|=Q!5Yr)C(N!;i)b~Wwx!AUi*FAv&4d|MbvU}jJ8xMqC$VU z8lpLIvJJz3un`aXb z&{l?+@z7|0^uT(GB|ZG@h{ln*e|HE_K%}B6UsJk`a_a>u*zpGY(VUtYgL1@L6QL(g zj2<0UcDX?>d%7)^IO12&)I73XPI*z{|M5}KpFg=712s1F{&Vu#^>f`b;j-i;(rMVFyl7;SaR=QHQ~15Hv1S@HR>|%vhFhNvgoquG6U!X zi~*J(D=+ge!|djlG}_7-HQb!!Dz6?#haFSFrOLMS+^povz|Qdz>K)1~EjDd89dEON zju7l~K@n^Pyqkh+&d6O2O|Tin4=>R9MGgIL8v?Od0n|qqZGCqqr)?}L3dvcZYM;~Ups(syBJYz!a*-ZTJF;04I_MoA2XHmvUo`g z7vdu}kgtCfIpQE@+L!9|T>o5j(hNMNahUdK7{5&+Fdt4xH-I}Syw)s@Mb5!^v*jLz8O;?adVm@ zJ+^;NWZ7`^QEjF^3A+3)*R=a$GgIiJuSikd(rv6g=AEhe5CPM_$UcU4Dqb^#%NRJe zbehz*Yf-MQ(#+9`^DaM$DX4T*)DTN6J@E^wVLCDPRf6!{vYDpP4C1`a0{%-!}q>s(qq~Av%|Q<0?fqE$W6;l*GtpOgqXCO8ad}J_hzTx)46G%dRNw+^oj@8 zW%w?8K-WGf7r9%ut4O`h+^`^HYM%v ztYCo5ouy|Z3tGlbg2k@xa?CuWlWR1g*5~Ge&K$jbz~yryYW=R>1^Mzu7KF=dF$#OV zDY2|RYO~DaeC;m0#@$o|V_JO=>RoO`Cf;zfq z?s>%;xi8r24zVLEe0oyuf1m}}jyO!*dXP1mAKrBX;>LK^=#%V(@ZVVkzcEHu!;P$m zOVK^lQT$G(%m-32SWl=C4*)n%_JeiU3|V2_F6OTnciz9syKw4Rj@A-5VZVJq2>(eE ziK~%qGC=QI)4?Kh&^Ni{Nj&&QZ_S_?mRLKcLC;u&_igQ33yZh^a_6r-uDJE9mt&BA zZdH>9cUH+^qje0I6*HrdrPRM(iG-*kdQvxz8$i3McjuaMfSi&@ci!x?PZ8wHb+1z+5j*W%~$>B z6};3mjazT%jWyQlOp10$C#r=xY>vkCTkURJqH|7Xz<$~u8|BAuzQU=`>q?5I-U!Y! zB)$L$f4j)w)K8EaHi=1~J&3y(JAu2K&x}34?_{cw$9h7hl8*^TQ!S0%b9&Nu+Kph+ zRxs&GNS?RN>Bpa@8F)T~kY~_6-(-PzJ(HV%eK#Y9S=_!f+8`iPkpH_x-UP#5Eo4W; zXFK}mH3R3d(<3k{AXl0H{q-_!Chy*wK=cm720oqvfA=2ylH4-QxES$aOUmG@_I!Ka zEHeMo`i_{_oNwQ20OE=bFvSa=diI%n*C`h%qBYz)41dM)CG|1eGf2N1B6RD+{&<7X z^zW39AM*Tl8%s3%r6BxuoeA008$Nmf-O+O3wo(1{U5(((=p%Q+JyM4AEo5Lie*%(R zU#g!c{a5%bw$$%)OQ_iu=aVP#xtbY-_jn=}1mI%~^~tMTH@FgV)iUaVc*;lr)7=xY zEAmwp1#~iEKed0>hmxBd`ijHc3m?-H&w353C}CZ>4CK_{<-8on^<=qFCluOvjj6-z z4P(nE!WZ=^`PHDV`_&*$0<<~y=I7sUw;$$#I5}`2TmO85naBFOkI_bn2Fed6=SjT# zsBdJxCce8yht*ayk-d$^xLk_Xa+M{rPuvGwA(xKgx3t-CLi1bqLD0%#VK6EYA!6%$sTi zPj^ztHxJSm8-(>8@Rfp{8kZN^gQ0L3ralkWD+W)E5jbFib^{xOB$W>mNEBEhK&~F=Yc~H`1QX$ zKM)IpdJMr@v<Y1*u+KwT$$_7ifo>-B{Mg2~)|&vTNRrQEfdpY3botf5#g%0f+}}SY z!}`qI)B8~saqKXIi*LV}GL&TVc6RKB0qx3kJDKfsT7|Pcs7}EoLk}oNURAr4ixK7_D=Bb+ zW-7@MfD;=m#&^B_TOk)d4v3d$v z$Jo7sT$Tr2Te2hcu$y@8)xXzU^KE%hu3aO1gYMmu7y>?Yq&6n%x~qgopY6xRz&?GT z%lY5%gX>RMThso+9Bd(ny&fxWN`X2}6eyUBIrL~r+8n7`?f{j#gpzh9qVpBCR`Sr} z|P*VpdkR{TMx`^`GxO=^D}9d-HLISN&SL zbN}#)My;XF+CF6*8d2Q@C(V#IqNix9{k*!6)GcKv(x@fYnR?8md^A(VTeX=?%>w{3 z!EPCHVa*b{o9yt5Khs0J&CL}0t&1S<yTYG zCdD}L1-B=Tdod+19j{NBW8ci%#gtr~jLofH7uFw*DUM#{((uSbUx5}AwOr=;xV!Vb zcL$!V``YREn$3SfE^VBsT<_qs*7fq$8h+grKH_TK2z?H`Tf<%KIY55-_X^c?6KB5o z;)7u$++59l!fQz1&u{N_80Sf|?Z0X{)W8El<9X*)T#GdT~OCr&*~GY=o%-)3ZqW0M?J(LmppulF{O?->_tVB5g+#w#Pc z-r2%Q&Em^@_xIOJLg~(yF2ZJ|*1(*(MMSOSlZ=uRlk6zWsF{)@lcA2q zTCRrSlXluyDEJh5%wz1|H#3vDlDv{blZJ*3kJyF*PU-gz_dV|^4VoO>_PV=zKU;qd zd$@w3LFB+oyO4N_dcCcpR_Nq|C(AAACZC;^-Uq=d=&-7#E2$tWGbul)v{%SffL0J! zU_D5vq*rto#~yW^w^Ya$E2DdnX*HcY<%qj9t(V5AT;OKX0He8RahG@&3pZJEzRo3V zi!FlQRGw&D5*~D1lHBS&%RQqzM`)~v0Lmx2NZo4Nqbh>1HiWMjk18^a-uOfa&GegQ}b~4CIK#IesX6K_(ws#M=_!t zF~$(1U%LNZN%yf!|0R(Y0535jGc}?+CWL{J52!2~v{Bx}!`sC#6A@+-NkBwf-3x+{ znf*-0ijR7(MN#i2lDuF1PM#iEb(u|Km9+svTpOBGV)3H zXTh&#e`L?1^31|`&*6t-M3MX!ffhAn))mDXHX_m;Q10@_bcb=eWqrx17`3iZUtXm- z15^~iSg<IK&~K5@#-YvgYYMyR$KrVT;ia$)%_GkvS(HCU z;V6ktm{bXRDtJnGiY)6ECNsK9J==$F4}oIV#xG0aOI;Mn6+O*^mlp*0N|sAj#9J2k z(SCSA<%44~NlqzNF49G(bZEW+FY_79{Ryr|=32~SWluxQ=G0=aXZyb&q>F^&qEOaG zC^D!{WD3vHNJeCmO~p$USh5Ao4Cojc^kVdcQ}xrcyhwFON2*FL>JT&KA!!dbPU$WO z2yup>k_x1sb!4gSp;itzlOIzqD8JAef#`@6*8{+kR5)DZJsyRIQUmTLaTja8EzZ&3*TyzS-MmI?Nf3q zq%#B#It@ zH{FFv@G6L zzr4x*!6ZEBF80=X)dT%BCki3Jq;%Y*$cSLp$ffhj5GS8d54rTl$`0pn7dvh+{seT0 zPqzor4M=JmKt)(0(D@%b!yoV~iwPM`!yfoT z;}?H-Zn`PpXN-NSW5v2U#{60rnVu6`*E)Wi|KaF`Ad~QFFprXsEg&}WFDa3sZHJQ` zHrBuzI33rn;Y`PPl=j+SN;s9m!r{!}Xd;tSr6IF2wknFbAq;c$%-SJ!43vNuhnIkt zij|BkCNCm&tWne?GdgOheRw3Q8GUil(2}qlyQ0#heSkNq3gJzuC!hDU2u!M-|H}2U z`fgTMjzqv@6DKy=7OxIVagh5r1ZYaH3NOAhCwGEsimbYsTmSZ2&wLgl3K`XIa86?u z;gpQQlo`>-AsgQ`K2x>`an5iqximogXVo*E0n+tIjMkXNhEt@}B%O{NstYRXWrx`$ zABr;%wZWRiZEy0t4qreY|3sL0hc_vEifWR5N^1TOBIu^7O4>=Ui1_$uH`@Qlc!CCdy- zCnQ;&)T#2|=mCGr4}eJ@hb9?Wv~k$Mb&7|{MR39=9J~KZ(xgWEExCz%``fK0K)0Vo zc|T=RP2xtf^2ih3JUWW!9~ZVS$_rq<%!&ETEb5qxq5&m&|ERky`lT!Xj|S`N7TVaa z0P&46^?;_trpTturqD+X3p)!v3%)ZDivs63=P+i83>sWAnfRE5n3NL95%GnhgQBy0 zb+Y*}#uUPAGAE`}ns%Ol(63&d&)}a zd(VT;3pq|2Xwn#w&MTf_TBJWxTX1}G=LtIrI4M1d7eYt;zW+4@;Q}N18w-`0^fWsU z7`Xfk_16_V6;ub7GyQ2QLH2TqP5D(BZke}0W=(c^cCAjiPVH7XPXSNmr>>XYd!=e= z<7vhj=lR=(qVrh?W=C*G?`g{^-1+or&(ddE<&s4JZQoQN7X&;^4&H~4z0Ym^Ze?F= z0O*rwx7?0KZW(@lZeDKX%v|l9-5mas-r~*z-yB4!aOhyLGb|>?z2fL&98l0v=w8S* zH0yUe(tT@ONZhQvnK{6GX0~Y7A-_?uQAjNmEd&pa2i=pniB%cd6xIrFnW0K=b+oSB z0A^r06!$k5x+^`+pG~Z7?k*$u@7uk-gMOv~wIDml9V{R24?}mCm)bqgz%2x;Q(O1# zKf`ebql^IkRr6IdcAGZqHZ$`-!ou!EIpL?M3?xJ>hO)x8gV$k+h^UAvh`pkx#NP4Q zL=Yk|;Q%H_hr{*J8De;moam}307`jygK%@qIVKAY6|JS};(l3I8LfhzaI)A|xF=FE zizxO%)K*krRQWJll*aJUFyKJfsQj+v&a7}6#U_I7iIFsOIAfccmbLoN=aRDix)G-- zr&WjL+nll$^q-3uar-rceHoHca3+qXNYHz(6PDsxwZIHan~rvB90QS1{`Xf3)~G{ zF`N?|HXIf>6KCTl`VMdBo74O`qry@#`l#vXZH#WVH}}W()66;e!erUNg|jF(SC_B3 z*8ry~rh(TQr}77*6SL{9X{BkqY_}{I*=Xu<)PuLc%2evLg73nR7s3%|-m zmm!s-3OBG$+-tP!Uv9oYd7wJ*H_+?)=$ab{4papy0KtGZZq-_644#JEGwz;VAs)jX zrXFbSjy$;@aPG2RHJ;a==RBUZQyY_+yWZ390d8GxC2sy~Gg_xSr#uJUm)$4T4;9|I z?x^Xx`~RG9#1;bxR|ELx1A?Bvh&TfhN&COYZ&Anp39(yRx&x{nAyV6YxC(ppC3nBj zG67n=LO413Sa1qJ#3X+i;xF7sND=meT|Z=AW)Z0-L8~SK2xn2Y$63<`+F2M2~k#i5?WG2XinxS2U41mjr6#Hdu{}+m_ zD@*{UNf5h9>?da-bw?q&XFhz6knit7{eNH-{~*yD{vI~uCfil%3ZZnzwcC~H3SLVK z1=fK?#zhyufKb;%d#Fb@tB1m_hRxJrYTa_Q7;?E9vOOE}!R`H#l#gIykF0foLv0I_ zY74Mxi;?{B+jzmgKEN*%J^?r})EGtxO4MJ9BE#SFaWUcUu(d{5ruwX3L9Gn%H-?00gxFGX zfhOwy+Ex7{>Vdt6JiJ3@t5LKR{jUG&b2%aa@F!*uIbaW0VvnYGK+`+G>FEOlL{hhf zT$ByUZ1&?S@6lD=H%gh3-c?9lt5#h=80hx=!byPF$*X)@zd-h#I~IJ z#hgZ5pN8w62Kr$5^||AH2j*jhqu(L@M@SRmCjP-xiuY$@!1nFm7!^i4Hu}HdVv$0FhysY?yJbu3Qz}oqOKbgftzy8zF~3a?l6oS<_o7~jyzi}4sX z=!_cnm^}Z5N}9$`UJ9tH_M)CtVw6M;O_DjNszn@3h9q2W*ztb)(C3HG$pBsicCY+2 zkkCTxy<5`^^J@`9()0<>nj@Pr_R=fj#e{vI`Pap3qJ;Fz#djtSnAEv+J$8A*Bza2H zw-er`ns3pF$`V)Wo8a@|ECz7+PNLaPLd!jY4$ZGCd^D#-1t2uizRD^Ci^yH$JDRvf zxP*yidO9Z&@Y5LrJ)H?#Oqi5$zzW8&yx>g=YSGJ8LsGrF!>#017{``LOe-_=`@+S9 zOAIubjgjVf&p*+4MG=phkD|ionHUkJPn{DnG>7rd$co@bm2ukX-7nB_pD6d^f{9)r zeBp)i5%TUn^`g+`qz=Rd9@_)u`6H=NZsP$ z(@X062Qw=#n`qb&Qz!cuLvP{K)6gZFUXnBZRTaw4bZ%V1{fZHc^&Ogo2n|G} z3oq0t8OtP+E3zhwIrkcQi|o+oln-W3BcF)G54URXs{YWc zx_9;7RbA_O)^ByN`t(K93gyczVYx_9Oj55rc|#`2B$W2b8jMFSbLQEXUaxGIO$eAcp2CCwp8zb~ful1 zqi36*5FZZ(e{Pow1oiBy2v;Zh)s}(^;x^(yJ|__jX-(5Q|~;8&mu5TSv}C za-P>RY|944Q(8v^bpxrj3@=62zo<#;Kr}8gP{n6TdFjcz0x>A7OqSzv_9m8266MSZ z*BUY23@SnNHAJ8}TzZs+tOBh2kYivM*i3UBwSlhhPV5U8Um~O_mD%OIe5Pylz_*ni2$(!?Q+kI{dYALWkxlyr&M-e96C0adoH!zn5uxNQe{0a5 zwRT4eE`zXy!a^y{bg?GS;%R@iq*c7M__h-O@t?##bAsnXC58MoE6CF&(~2jnp!)FL`Iag^l!37PVz71a>Rx86un+77|SGm-TDXY z^UJRe)4T1n+6I0=akZ?#F9km5KhJ)xA`H{_F#$y6fD|S5F0a6Pq2^AF*|+`#rW@jo zEm~dWyJ$f^VMnoC&COd7$e445K&|d%BH~B~6DNm+1S#@1Vb5$JP-=M1y-QnJKVpcQ zb(X;uMj^v8=Ricj2f0M7TwuaU5>{wYirr}Fb$ia;EPBS4h<=$EVc?&P>EQqdX4av5 zzOKLut#Lu71dBS8f+>9=d;{#WES2zZ_`uTzH9|T^(s zy?^LURmD!YwZ{A2lia0QY-aRy;%-CO$5SZ_K1|*j&9OHv@1}JKZZ%NqW@wvEQPF{d z;U;W|8|E9a2g+nRRO!t*$^khh#r0-|VDWMqHoy(C;!`#R#G!maGOMa7#Z#W$Uowy7 zatrQ4W4Y=pRdWG4FmBtsN0FWEpw)XJ$>7_FFs3>y7C!}4v@-s~?b6!LLi(h>1C)5v z$gza$f~l&RRlN0ody$f1WYVtpB&Quz9*G6VYl-}lpMDZLX14`?J#U;xjV5lB4Qaw* zc{e)}@b&xt_CxGT6^yH()6rblBv#LGUBmLXE^~g8kp8SWrg3g8-9|#Ep{n#^)}gG5 zxwKq)BTom8fx}MY+IwYwMQt^?3@6UIU~1=WQPgG&on#Rqj1uG)oPwn5sPU=Yi(J+w_vX~SsE>2nZS9EixNo5GY}kCM)!doq8NUM#e2 z-xk@1>Qb-G_&T)-sMXog?R|jDPw;L>#%v^6+tZb1;}@o#?2)HSQJ#YoAa})6t5^v3t84m9`N-@dF-Vrmv4pS_QY)SE9!Fhz2cM z3lodjuj5q~SGDWcaDXf!20?fcxp@5|0<+tmD0etj(>)=s#r87zJ{R{`Y0Hpi`s{`P zwyvUwHs$Ls*6xeIh4xlGs2#Pu3HmdZSB9+F+WFUBhQ%Vpc+4!jb>&i;^`th)9hg>Z zmmtVo%jKY%a&249bu9*x+BGK+Fv*F9tcFMp;>l7O42;*-n9z%CY<{-V!&T^3ofiS6 zhyZ*PD1mYGmFwsSEH-%IGX2uiMN+W`rdx{(dq$X1zM1v&oq9?32wmiE%&rB`H4bxG zGI7aoT{b2v>4VHxsqMDOxxe~jkM6BQ(;Jg`8MJ37931fSf+-?7{dcsX18ighw_Et) zqjb;YHD^W9_-dKYJ9G>(sPD_rLe=BouZ(p+QH}YdW(PZU49_Cstp{>$3(=IKxa~!&F|Ym+R>PJ7*`aH^xunEmNB2iv-J_zo!W3*BK~0V@vm4scv7LJY4;{ z`dUSnaxMuUR6`yUrO}FjMDL4GTDS6udlZ z*~fRpAYWK55KOH{YyOvj=__}H1Z%n`D4sf%L-x`f`hhyFPxhiM<{NXgx$E;xgeH@6 zc9im~HxxM4!kNTl27Q~n@f~A}XS2Hzxz_SKwPPZlQZ+taTd|cw4mV{D3 zy>l8DiT8;6J_A?Uf0Q$m1++oQ4{J)K!~8+eh0B|1h&CKWHhB~$F^S=f5Qois7M@8M zCu58rh6^1WDoCrdOVseO43k(b7Zg+8;QVPq2EJZboJ~2kM2fsr9@K@yEA8`0%fS6H zfN8E)BGBK;W7j=6Ly_crXEeyUL&#uobzEEE}fH3Y0faCK(B+i_$FVfu1zUtBz#+TWHnIC2#+~y z2vJ3K&>GYlG$CNT!Y3ts|xWuYJ)w1^(?{tHWSDOP%O5@n;kq_4@KMv zmB=MZa`wJ26OCdEF-|T~4Zuh@pJp;VR0zu@WC_oAjN`i(cLB7TmopVt$P<3opEeIQ z-_aMhF-fCFmvFK?C|#MeJ1QM(Hp*%?en=Mew6Ii5 zfKEY>$8J2#Bno8bzEZM#tS8p_NA`j7ypofON3G-a(qCeh{xi@Kz&9Ji47W?>+2O~K z!sSy|_k6U2D9<*&zTZ(uaVm0^j7#=G8YaiMNRsWljPl{o&6uuE`A3JO^^yGXk1I>6j&M#5)+E95 zh#}68bw*(|NzhjEpx`eQW$7%NInJ@!aL^h|rns5}z(Fp6^X?=NDCl7QuzRjKJsNp* zG<4$9EuB%i4`pIRp`BDuRHpEi^!98Ca{ zS~pT0t(J~HX6mhjfd^EfxfcoG1k6pH=3&1(xT%||M5ZiyNuuHrQ(;uKSB&XJ6I2jnw%@v%FF$!C6qZ< zqZ*(7ua_~?pMCs>XEDS-c7JK<9qp&c%wfNltR)%I`i4Em(+#B)eDCQEvr7YY!fFjp zNq6)oryqE|G{DR+`Q%R*jnD_a$N63R!>yNPDbSFzlb5A&i>A_NAQRY~xFsKZWaDKV zMX`%xBpIC$|L$lA9BlG61!B0m5?!%=428PjD^BZ3SZg(h`;ac#VqAWtgnC6zp(u6? zg}Zgf*z|#y(in_6#9pxk?;LU)016_O#L}RXPp{+5uH1tM7DFqjeGwh%wo*bVhR^+x zP`Y>Ox40+S`?Enf53aYqdXtEtF$3+s@OM4tX2i>dGb}+(aN~aL(JYF~ELyQDeY+4U z@L}n}xO4vxf`c0WcdtowU{vtqpXL%1FV9Wxhpe2(o*Rr^%{O)75FDO|ZCya~kK62@ zH6|a??*~qO(T{D0yqCF7LCOe5GsAxgTr=G|C){-0c#_GMQNdTIcGHX$ckKF7qa6r# zBJBe}{tS{bpwvoYZUu6)4Zm~Z=hhl_a%Fo&T7Sj24XU+}j+e-!$XG{%wK`MQUBbl8 zm_X>J@L{yi%=hg}JU3Z#kH!8$!4= z&|k;!l^G(qoS-!5$LZNMxtzFteJa+!V#y-jxKfxu#>N3~qi`*v4`b9%+`du)398Ew_x;H*V2p$h$VY7uL& zbl*FlYsVXblrJz^%Awe)GGHgQa(OcRTjBa}keHCSAHoHd%=oLST52n&H`XhExc}KOt-6)>r8TBwM=0WE8+frRz znR^d&o9=Y3IRtvNyI4EaP?kwRS#<`rfFwO934*NvZ>=GO@ zV_c2DQw_?2+6O`VUJ~7xo|7u!yG@5anoc_R_=D*_>rT#u9t?rf3)#$79SAoTCJd*d zdQBbmFjkY@Oy4=bj<2+pV6fp~no+@FCkMm_TnleC3jZT6!)vJ-?^EWi6Vq2x5C5?z z`r7X~{yL6zBCHm4Mr(+5;JKfa_QxxF0aCW9WSI8obJPihlHk8p{IFoCIK z-BeE+t#&t+9Eblf%l|dq=t!JBM-9G4_7*zrMj_bs zV+~3%@<{P~MqJ8)Jd#s$IG|Y)<cJOS-~Y{m<4yrw zgQPFpb36RVD&*4E2cc0%TxTn$!`Eskdea9n)p63Qhj*m$`=YnyomSAB^)vj=WBRaw zru$j`I3}jfM$r);lw21dq_w{<|ASBae&^O>#J(Kcpj(N3G4UCfEd7!=cgPfzhxe9` zu=_C*zis~$Sxt~NZ*YQ6e~U2_U`U;>IXcsce)Tu}ec#Vwz}_ij7KCJVFyw99)@I!4 z1HN(7+G9*4??b!6T0LQS?Z;-6|Z>l76cQGv3 zuaLjPmUBx(+ys`o+LGDF9*{9SegFTgf`!X)O>7i2zr{Br#c#fK)O%2i}Z(T zq|D|N8Cn-#41g~{t}RD>hBUjmv_K+~O;QD{KzTy`RJ=l0S6 zz9LRgfbhF=3msVb0>Lrnb9qm4JE{`6>7>5Jd$>oMWZ!~OEv?c14~)XUNwUwqIT;Av zBko*|pFc<-W)eZcH!G%nyNz0Dd6i?fFLWJIiBl7<=2EN}Xg8{v*(jeOebgEO;C_Gn zruNM%iOMxIBd}DuAG^(n5${b+Dx$coZbVW!^sP#|Bl3GzS>Q&(iLM=JUr695v^7n< z|EsW;E)v(M>J^5i=UkzQRN0dw$!FJV33(sT$eVAUYX`5+pB7QWb$K8^Di6 z8)jN%m&BtDU)u^8E4AGnQPlE)DX)0pCD#MH<2&LmneFDAo3DZ|N@JKaos+wJX!ZEh zg_=aGqETjiUKVUd!lfC-Q?|m7Sx7W}RXmB=TTQ}1C$mor?aC0sLrkzpp|mWHRvLe~ z{hf;wLb+~Cu<$~^XgbN_o(+p7=jWby9HB7)+I)`wP=Q~wN{FB&!86EI*T&+I>f47z z>CwytmawEmmE3HWe!RP2{&s|r#KJcZA)Sw1Vm$bM#%m9Dw;xt5bF8!tAFAcv>c{LB zE4cDb?c6O&UwxxNsn5WIqpUw%Vx|}rh>&=P8rJ7QOHAWhyb7&AUyFdgbiDN zV$FJMv|)Ip50*CSmCLDT*vj42%q$0u3iGS@M!**}>Zqd@!P4rETm8`~KxwIvv)Xm| z=X#DBq$i_T$KaPW2RNH#M=FS2xDBW5u%ZPai6|CG+~&<&xa480g9|PL0&^0Q3&6Na za2-D_pQ4BfnrHyo>UsZirL~hRg9dZo8+(4S-qFr%o??$co%R$YKAP7q0~i2MW`(;I z-|{tS))XnuwBj_1gQomcZ=+Pi>B<`~X0Z!DM5-M1bH$+=HDE;#yYnU2>8HFsX^wtZ zN}>n#XyS};uYpHH_fV->eRR`36p6-nuvEh$TxIlR(bX%Xw_L_6u@5vldmWg2>OyO& z?a?;#Z^{-dc*JxoSG_k42sOqPjUSRQvCt6lo&>FIKi;|C(ZA5~L{*c4Pp4o@@1e|w z@)*Ki^IhXQgmMXc%j-}X&xk&dNyhJv7&;<8!?gZ+<9|kf=6j}Xjp38XreKN_jDs4L zMaTzAW2kiJ_o?yTlQ$-L2AmWsDCw(e()e@C0AB=nVzOlxr(afJ<%t7cdyCc zFnv-#QU&Do3%d)XC5$u2L8&4-frsrId7CAIMW7kgYdIaiQwQwB6YW~`Hv}O5=I|ct zY$}C2w_ZTbkh&aeed@1%>jCX6*(Y`Hu@9&&IXlB9<{DNz=B#m=1HM}Z(ck>8+XC*` zdiz}pmxHOTv??lP+i=ftt<96v{ACf?$zlD@{qX(pzkRy$)Hb!7RbJA%V$Ko-Fa$BY zXf|${WRK0~fB{rylmF;=WBbdL;{*LhOb-tXx_&D}lDXy!S#2mVC zyi3!RYctx#ZcMM!3DU;Q*~JnrE{;@Q{53|-!77pRMVl<`{E?EBAj4xOwy+ZvK#TBWzbNfVj@C$D>gP!5ZpC%o^r}{KYr7$k+JxJ`%ly^*7Kn zeb=9y-o=}$Hx?jxcf#e?=Aq&>)-zrQbxRPikNS7|6lo=D6C899YoELy8o`e44z)x6 z6J4!>x7?e)Lw$>?x8$2#2mOcSoa}dtST+D{{1?9R81~r0qP;=eQ}IQoja->0fw2@X ze@y+S#woB$yUa`DvCg*pqU9p!TE1&kHIm-Tc?ZO$up)aM?h9T zH>bL0L9klCZa@6pQZT)MKJzD@x}6 zEC)pig`vI3^vL8$3>-XGSJRH9>)%7IkwmQUrZpaaxmR_p8CfOAyIH^X9s4Eo=Y;o) z_j+ah6MXy`N1vPQNcNxTRUqk3&iEd^T;dc zqG$iHg|2J6_)Rm~D!gKbo!LpoG{P#+s_ayHk#f;>(W=^~+D(_J?c;*y@@3&ZAi@D} zjnR$hk=QNSE3!OJ__FMB$h6lATq zR6lhqm~F<-ki>&|B3Ks;)eYN^C|f?`?~XJ_1tUmG3+w)(u-&pboKavbRF}k_yD@+d?vcB zd9b^>yt=$4x=u0GF#TBf?fnecM81NCf&ikVVpAi`K>`W1aF(#$*{4vraJleWaB~9| z3@*1idmVb?4XB@_?0?(4*sEUc8%SR5Zar@`5+_(po+WUTJ2@X{?y*}kux9~;&P}2d zOxr?}uV`3A0?RPQNk^sO)>L&kg32&YFl7^+#gXP@{%dG*tejZBJy|<-N!Yc~OMZy?3eI5X62pltKf~?o zu)_Fs#H@+o_t5s70>!fS7YZ=;6#AmEuC=EjM<=`o)2{R!Sy_}d9PyO>wH%^QNj&pp z*C0mayA;+Y*5$k8@2I3bskzg6<)4prJQ?qQ`UqN-bYR~Ox1tKfd`e)CC~ny~YL86s zk$7T>bfoCZ(|=hO!Z@$rTge7Uy+e;geFyLQezkxvKl`;{ZDQ#U?T&1_GwKTghjpl4 zZU*=4fk@0*pL$O*u~BZ@Wray&J9tM_Eis`)*YYe`AR#qam*}k{ z>nOjCr{;d=oOOjJ;e+iBL51U%?t+7{n{4 z0M0?{y^m(mQ?1sqtr=;<2qsO_2x5%PNqB>ptY$}p15ht$+x*3uIHUY>bN1lV^wms7 zqFHZpFW|+Yx>C*4uYud<%&!!B5rSBzb+ZnzO|%YlIl6K=L%df)w0(@mt4j{!+@9PF zKYJ;6@^5O9^kdjN`u2=Y@7CMAH?^yO9K0SU*y2&Q8x1T*2a( zg9cP6G>8hN9$Y-peWKTebtMGztw!WxAtXlv6RyyFLVE{bb`<;Y!2BEoU4Mt|l-&k} z1eS@E{nRYQBJC^a!|Kp)kv(F9N2?30d9r)5dQ;?M2=$k?hv|rSq962`hH-`9Po2oG zu4fGcS_cB9-NXMCXv_+#q?Fyy@w8=mWdKvx2h?lvz2f+VC(JaIInyQ*g{pt!E~&R9 ztPH@HtfcWf&$RUdR`RbNyRT_An=S{lOVwvCWigdcgevR-NB$Z}yL2+{u~g z4H-=a{|2_{N-fPVc;{16Iat4w`MqrufYhzGI-6L#nbmvArpRK^tHa&`CozgU z=qdQh$+%*zq>_8||8UM@6Xp1e&Hv>3(9H-GBE*I?{mFRALpnElS7HnGYm$I(k>4g3 zl%Ij}ktPZ+l=$+74!ocIh?#0U6R6gz@mRK*5a|`$e2f)OGuBxN>fsd zTY&FSDrKU-Cjc_zQIxGT-$NdL| zi_D*W8*6?nKURYPIF^W980MEE?FbhnXX;x$MSgVADAJYQS@P1BA@#=wgD7-L(-|C( zO3;{2n1*ysd22a23KPMLwd`82H zYx62O=s4AKSf7g&!6f}q8&h&ID2e=`&Bp2UEeW&XZwZ!!kG3Km7xhiYpE&TwoLAkk zndV%zpivGM$RsGWhrE?wo)c4oOw5MnJlzmi@U3gTaS+^v`Bx_eTd~Vhr*vcu#%$nF0!cP)KX2@ehkXoA_%%g(q-(w z-T0U_Wnx?ZhWA7?(gf?s&5F$;#~pzN)(Y`^&YuUp$s5-r4f<+f+KM$W$Nv5bU>FEo z7Q0AT5FD_l_ub{0b?vupFUydlbg1#JY*G&x#ca^7gTAbjY5%(`bp9v+&0)on^LTv^ zU}x?)?H!(yVguYY10KeQsvamC4&x~5AHKKr3Es=4x;@tV`2R4EvhS~sGzLclt=V&N z)|!{V%4e2Fi>(f=AwwEBo%=`F8v0LPOo5@fVIuI){#nCpRJ?(Nh>I7ZW5emk50n&L za+1AyY{g^xQ;&d9U4Bg2!v5Ug@D5qpFh4ssWnEeVnt}#s<{?D!FX6$W;KMOD zBF|e04a0Rr;6N=vm8k|J2Jd|Q;z|oHw&&R{C1O#q^>txu?1os)l)#u;am@|fAOd$~ zYY{CqIB~$kH8EG~S%+vQIou-Kkf&}@S_zhq0ajg6c6ZW@I~=>d8ey@P%GM zbpGK;c&GCoyN&AS$EsHXeu3G-yT$X@t+efTo#A&U?KpS*a$-q&F692@IhE!`J@B5t zxH?a4z#UuW0*2W~tZUW}fgncjAGBLjZXriZ+a>v&$Gqi!A9{aapNQ?nP(BfVCtI!t zBTwe0Sgr;!3m{cBW(Q!UHl?IBfeH`kw%!OK%9`Zg@V9IDAE0Jk6D-;X8#+fCe9|qv z{#mXXEUX(mwD(@s{de3LjydkY?4q-~s0QRptUAx8!EJZ_E=;zit#b z>yGfKc=h@2VcL9GM1f?X!|?-V6>;i=mVmlWrz9P;ClWYAvx!G?=%UoAGhoL5;U`IW zrju|243*UGtoiCNyJz8dN(!Ns*t6k6F)6gG#bdRdC3-=4{*DX)(U27Kxo z!5*%U`Q%42fg98KnT3%?a_9UWhE+9qZXzXc$7T~b1hUMJ3uy>=W^r`1UKsC7DjF9P%^@XW_NI#2 zuAC$^3{`aM)=5N{OLRRV#ggv4MT;p`%u@CYycmVeev-Tl%v_W``0PC<|zz&`BL>2;xn7IjeEN8Z)1JwAwEkg8rfjvw3~Q)0bcp>gE7_cNXvJx$-IDKV?0Uc+1jYE0VFLMI!YM4#9^kS5?gb4Jx>D9t;F+%-wpGyq#ONFs^tM#-Quw4i8pk0^3qG2Cv>o`>9INEKOk3rV2-r zx^`*?fnt#H*TLMVjuCpQC2ylkK`y`hfTv}Of+R^^R1g6`^%|sX0*|kxW4s$AN`aHkN|tEB zJ`UjrL$Y(siIcdGOxC*}rAtclluxN_Qz%P;gWBATq)6MWcfk+ejb^?fcK-mNy`XP9 zzHm-~dZm!qroHyzWyq$vsV64of);l)Ke*4{S}Qc-Y0@M1+7W%8=&!v6AQ z&A&9m%{j9S8)Xxzb6|YLQd7Or6ob0qGezed(i>YKCc2mrkfif$NVwH9p|B|=%wr63 zJ~-y<7GA)car-=*G z2EcjAAz{3ZG@9O76F^W2BcXBJ&}Y(Jqm8Srj8rDvD{mJoId6)Fh&4 zZ*=j=s1w8Rx#r)~^V;LI*`t{vh#HOdIYi+@U53Z{aVa)YVM+wgIL2>l=H#KYxN?J^3yQW7+mT68i#SCf+GeI z5x>n{^Wn2vp})uB*xk~uQ;s`vAOW=#=8>`)oa|#MaO*MYRuwRtnrV=P~INv);X;rf@ z)GM-v(Qu$%_U;y>i~frTwNM~|104R6`l~o5mpW(`Fc6u@OLwcYHR3{kB{dh63H$e~ z52a!{85Twv-+@%r^t`?|n25wFhiUt5RdE>5wgue8nE6 zIv!PVM$}F__XK^s7AZ57sQC-CKnbh2cL=LW+V$}}4y1OgUJWqUA%U%q>e}Fz$eWR+ zwA%RRsg9*6GG*pwl`cco$@k9qj$$s2;*hiivm@+`SCVVs-(CMDs~MBAmn-^mx5K*} zc!_a#^U2VTogI%jOL!f!(CaHhx0}|Yt)T|o{!|`7ST2++;)bq95S9{ zx!#LZJBcm-iqKTvDL z@>Sq^CxFLHCqF*PR;A+>0D_ z4QUf`8JcXR*Nt1dxIz)(Y&1(sd%VD*a)u4s!OoCWDY}$=dEk85@9@b|9Ya~a7)t z64IzoIQ>~u8>x_V2G#O-trw1HkbF{hz9v2dtgUK~b!;klXU`?v0ncCKy)7lw^)p3z zjO4q0;}s`LkTs*XH_9E&yF#Y~?M!|WPW+1ktYIFeJ$9;Pxu*3Kgl?{-;d)tGN)Ndv zM5o~5!p%SKJ7}*IJg_fpURKkC41}Z}(gfIV7l0lUgW6=Gp;jUlm*?{T(8E;qU)cmo z;MrZ>xmKdL3-Jr1yn-hO?EFes#wWVs*2t@+ z7QbbN=Q5IxEfMr1e(AM~{Yq54`#K?SJ{h?$fqP*ItK8G-b68}Hou@xNnnK#ZLs6c9 z>X^50kJMDidoGjl<6A(F@~YK8pXoHZTNFt_ry z@ZDpn*jpHe(Vx&O0ylJ?WzFJqGLJR4*SJT>M73ryb~6`5wYT;2y^AGH?pWI&++c#5 zacsJI#gRgZk`PZ(ZYiIF{+UJOi%U%%aGtla^VXi2 z@5npNsv;-cRIMA{i*peQ`Q7zNdg4P74)Vjr7pJRUii;JAkF6$E=$jAH+_%}XN7fGU z?rH*vKU{3t@-e>aH7x)Rv{s_q{t?u15N)1RXs$$n19DT?<&UP@p zIBvQ5c<0UCFiUpO__ssmLuUojAnCkR3I0|1t3`msW76whImzEvMZOx4nHYDcVB|H(!QBN}a{pCE$nUN7X#LFUK`G!K@9Fz#~DHp)2n zdL(+{CH59I@@UV`Ka+_fo)ce#Yeb}DI`K>9t@tJm2x=-(PM>9$^gXS*YIlHCdd4hM zMu@0if>LX6=$%xPt0UNGccW3*ZqObrt^l3t0qMZ*5jU~uKh7*$`9aYS{mithDk`o$|42C{%8gf4#f70J+ zF6DVDRx4_dD0)h4o&ir7_Ox~lwIQF-tP~H{=?>NTcDQwF>Co=e=QhcZ&=!{oA?UE? zCDjYsKT~}O;-aMO&Og`*g38+Oo@Zd68shs%ymYcUD(_&&mhbho>SVi{oqT~-=y*O6cJn|Qb=P-+;;pMnPITRo9yW>;2GbQWnhQth5Pm1Z_t9s93) zkAw{zrZsBBo#C5X@OQ0)jc>7z)zEkthcG7_W@25G-dpVRz$Y$q_0K;Ws><9wHJs(u z_cy%~t%c951iuBBQu*H*L%-#$tHSPROC=dy`KWdB>cn-QAGxV&Sh>XH|4yqlyVkM1 znwRW;DfN6g+EoN93HZPYWIS6-2>2j;oP^Ct&dshaH`m`BuU_drbe>UozX-g+0KqTERNdB&Bh?A!UgwN?pQgV?rXM#GeqKI~ zef*{z9cQ^30TFuLiu&Hh?i^In+3Ch9)|h1nnUPRcJf-=LbU5tKsM;yLKC)0*QCZc! z`?7YAdgJ>7GZW4g&0?H}@0?kATRB=ObMnWrh(3m(jW?BD`EOU|7po`3Dwxb39lf|4 z_3lqDy{~=gVfJB@=8ajzZPBG@cO|-{^Uwh6IEN=I>u{VXcc^R+ub%k zpS_GsVVx|ub)Nh_ZSZPa9uBE0*ukxw%bCueK3l-_5y?jO@w(^Bq;gcQX*W(e+cRu3 zYZ|uAT1Xj@71OVY-Zr`1SI!zq%a#L)FSnu+Y#`P+Er|Zz&3vl~`$b0kWv4f3Kf~t> z;@m~PXlkp%8?qA{c)c=tuEXA?CbUOtIj;rn+`9YMP@uh4yq*L5laLF~Kc0@}Pn`!t z%iAJM$V9X9OiCx;)HRYuF1*Q%gT)#Tuu&LD%NzAu3m>#+JKvL4(@Zqd%n4ZHrCA&% zAIrLqq`HkPYF(|yse2%oj^o8-M9bmOhclIXc?Xlt~s1#7X(%hfw$ za^iLKuc(U|h=&l_3w@S8bMN#0HSm^W#+ewP3s>Zb+gj?K;T>WeFK#dQ?J`vU0rE;; z$F>}=b?9wFZAgjI`c-8%+wiM}-x)vTp1EG|*OhYj%wt%f_OK zZ90s}uNi7?)NQzRU%F-o88Lh9b_1}g4sM=yvo&tD?zqK`W1K09lW_B8x*I5~+BKRO zSxGNrRmYpbH18Nc0+VenV%Z%af)x912;K5AF!`_E{$v-aV4hzyU>I#cUpf_$WYcXh z1di%cP-s_>^M)HIkJjatXbGH5&e`G(lHL%%lC4tJ{f#?kaTBkZ7SvMcvB;`Z5YKr9 zKlsyf`JUi2fH-A!CU^#gXG&(B7*)S&?Z58V+MbAUq^=n#RXTDj?~IGpDpHE*LQ_?! z&QIfU#@~zfq?SEWa+~IjnKN;Cg)R^SI>hlN0UbnmWPYThEM(k)-nl!J!)6`VBJSEx zn%x_3NEIV!?3?iv=E_too!t;=S3S6EwvxP&sBQ=X*VP?tPsuOE50!F0%a_m)yt7p< zolfkVS9&-1%dW%_hu_AUb!4Z#O}UC0Jd=j!T0fGLEw3YnJuPC?n6eT-$k*esy`4tl zHAh$X0M9Mn!i2Gx{~Tn}<7*PB=Vj{sqeupoX6H#={2Yb&s~^fa)x{$gZyF{5TD+EAC3}EjyLFEuD{2?j5pr$TPnxRao$Q?RL7g z*WF>PhS%87+a;zP?Jo zEYrs&6}_JRx1WN;zBev3EhvFK8dt1J-^+X8auGWa(|eTd!7{Ey@D%#$SFR$&p@rz!YqTZ(7t#8gmoP%;AAk}x5CPC*Cyd91#OPnK#q$Ia z38tBke&t%^W((oq=5K)5X@WZ{rbjNe{BfKJs z-Tn-Nep4}o>-a$Wud)pJr7Zi7h29PCeJRWOVBZkGl;!_m6fA5_?Ks%}Z%cOAFHQMB z^MC5fIzHCMi|XChuJ0)A50>Wx8fW(xo`U}7nZ~nhHswMrgfW65a`HN;izF(&`B~|P{5fGU$;ol)H_ zEyo#-s5L}z;RNCR*|F>-Q8Qy7%-8YZxL=~zVZKgvngP#NS3Fsryol5S<6r5KTIF$h zsjACObU0>~#B|w_nRGL%jV(8AQ}JiSoNRPD!+GLdhpJ`bod1P7!@^nzaNtnATv+Nl4sPX{M z_QzUFvD1r95#}7c!0@!c2VL3B=pCN$D{E=DAM?0h@l|qJcj;;R1J>0A-$vFvThw)B z-Z1=%&agHLVLuB%p}@q__xs$qxx}M^XPAGr;T~P?!EMLI#2q2HE~NZ#a@a_6D9h1Z zY$vdDsvh~=EQl04Lmv&H1ng)0BUE#IXN?c~jHiNWbVlklyg9rxrZb}R zcQ(W}u=MY`&_(Yn1C~>kiUC7HX2OR;hr(DwSi-xxuu1?B#*}O>&6LX&!jycaJ^KF+ zBXovk``!lD_TxXHKG@D^Un!zCi1cr|-`5AKrx7QO7BRoVQ;024l;Yd4kLZu^kNA$j z%)y*-*kCZ}X&BV6jnCdA{YKN7-5 zx%IhDxp27-Q|d~yeLoIT2im1OlJ;(8_Y0vHgeNMQY7fHvs{a%V$!DRr&_t31Wy$B6 z{;(DxGaLOyCa(s4MecVXjerBrRERLAP?U4gG%)=hK5N)xN_>i9itDQ; z?1wqjT*Kes=7lL!C^C@29!?}TxGj{?q(Rlf^deLXUTmp+M`PHvogw7K!l$0vfp?*D zf95CKgZX#G0_7QV=Agqi+o+S}Lt4Qw!HNC<1xrA*ztjBPXnuOe__@qa;>VaD!wBdM z(lf$^99f809B@C%%!1C_k5Y4{3Z&wWS>N=;~(` z?>P8uR$)rlTf-`rR1MsyE{o~6TzoF-^0F%E&-Y-3?^ij@YFizsJ=MU>99^fO|IBP0 zT}r*gb;*{l z-EBQ5deV$tU9YLXIanWqQ|{7#j-F=?EhoV#VD=^bULnxihdupK*%Zp`F5IO*<@K9Y zPuaAlyBJx!YzC52@|4YKdL3hFm(645c~9Aj9&=r{=q+=3X8ti>6w2-q%042L-7A!R zR4BVoDEpXD_Hm)?eql|6W1bSmJSB{IN*ME$Fy<*?%u~Xcr-U(2Vay~!5y-CD4X0IR z&iFpgdC4am75%T{la7eGqFZ--@v;m#iS(?&PUkkLG)@8f;oYw-SR)T}l8a!jBRFdM0qD)9FOo=T_g|;Bc z)kR2_-F2g%uS37I_dSY}-)NmgDvd!tj7D{_^HiF|+LqL1XmhhVm(gYpE40|ML*DW@ zR<7WapE9JX0e#w8PIlwKw^Jl-A2FZ1QPo1f;JDE$R5moBDGOGwv*3)z1UWxagBi)An|t-!#hi0^?8Xl48sH zcb1zIS;6V)EMLPqRP?HP+u1-1w%=*AcpdXGYn@~J=qYBLfCm?6cPNT7i<@XCo(dMjd`_k%q*TSzk2K8zB^H_oM8~ zd-Z7@+DFo;#4CurY3!2&$&`5J+%yIKO}w3!zVY&m^wpI`CSFZlgKU(AvCQ-MU7mX< zZ;5SBSr|(kEmqm*4)W@%jkY^^2_DCmF!u!PViU+q;?=R9!TBv?mn!U?2d#(OffT(w z()*y^W*NS;mw>ypEY`#qaF ze4c6m#V$a;iQ~6j#@Zb4KDa7qZyM~K<$W4@iTg5GdRzI?D9HlJr`H}`f}U%z*7l% zG`+zuMT{kAAEwclou8LS-l@!6WPL_5@8!iIn_HsYi=#9z@)EE}Mq2X%kNh|rRrB-e z;Oq;Q(FJ;Fa;(T}8=VgQ>F4d@^N#Rd8n)YM#h<)ZwS<+f3T>{VFC&A&ac*LiF8r?` zugPb)DA?+vYNOqt9j_p&Rue326gEe;zA^pDfyI-oxr6aE1zwW1tHkS!SEU7`yf+T8}qnv)*;{XZDRx1Hbxz&;Zzdf+t z%$8ue()hdw99#<3`zCTBX?LUf&2C#=?Bx>r%)!f%xd$E5EkC!3b(byG45YT+LeqY( zk$J*6LGB!^k;7-g&ov0(YADx8bQ8K#^2`=Fx?xd=-#c@(rZsYSUEosW%tRJyAzbpU zBwsPX-}2&^ms_?*8dZ{8mi@+6{f$nIwEKp;jZ-1Ln}O7A2W(Y@tx=J8*Xw&4JwP$| zD=O%Fk(MA2G{~Lhd2F*S3dY6F8(DaL{&yD{O%W!xIH%LrSD^760kIGgD28BxBzm*) z49DlOB@yeaBH!Z#Ms-P-Ue|x+R&K_R2*_gWDw_>ybFJ>TJ<|?0ICIiaHag-!H-usR zb{xs;OZp?1Uamia>E-$(nSOjg7TFaoA?c&b%0|7sT)zh%w6HGrO7e8mmQC<7SeCeU*;#9k+$Z}t_T)Sy+aA;MWul5d`5Tem0nOVL-GK00}z@btS{MW$`0lfp>v5(7N!=0xT4s>I(8roui5cQ z?ayHMT|^2RA}Xut-W!YxB)-dgBcq&owpqq9ToaMo71U^k^luSX*!m|F#WV@+${397 z*7cD0Yrw)`>$eP@*O_$+M)2u$6vg&ea6)MY59#CvDcvKHkWd8K zS(0*zZ!wJZ&m<&OI2238kW;Ypm*OR~M#T_*677fcQ>>qh0mS7Wt)CyvqDiQ08@=U) zIKwn!=Q`?1ah)c5+EWD)w@u@1Li7cpf6`ucmhfhPKZl5l3mYKCfaZBz=KWpRFE2kB z1C)`YiN9PGVm>woQ)f@w&tKEBRm9nLq30xoSjP9OEPuf)CPfWR{zSrKbFf~`7RlgnR8^b+hKW*NC>{LS%?khdv7vKdFD&6;Du;|C!J~A6_N9ChVd|`w zjT(GaIg(Jv&Ntad3g!x&mc+T4WD0mJ`R3((h++6SAnP;?7ZxC7_7L zAvNOA^>QwS&|p>3U6Sq4(-2ioOP|R#OdRa0vNs5%8Yy_5`zja<$+A|>awgYnHJ4bQ z8OwU0C{pZ=Tr2}kldru6S@hQ+%S&3-QPLf-3~G?xt1-IV6|E~}1}bbvq#6mfO{JE0 z@YhJOjxV>?G-yK!$GXs?a*Y|xVqe*~RWix{@2#PrwiO)e& z8hrXX>)2b}HAH%9jO8ShKy6UAPO?W4Wixq>3X6c7?1+i^XIQSn{Q8EnaaZYYUW3&+tWHxojQyMt97T1^sl38?OGY0wchYuY zxs7TIEfvJQun438%`M-1uo0Z3q8n;5K4>7uQ$&AqoF&6@TtgnnW|$<)Yi8G(qmt@S zhO%;KI~kv4?7X2yt50a7!nYJ88*M!6>sUW~XRQ6p6PtUqzhS7d6iGfF#lY+6)&9D| z>!;DDD(8VEU(Ss68f1s!i7pUO(BG;8nUMXc3O<*~$5xP;qB6pj)ZZ%Yw#m(g;ac zS$&p8)cznOsyU}zwvyS_uad%aQJ#I6W{9^m&j^zcZ8=0oEHNS~@G9?!J;u?GSy%6R zNijt_ch<|2H6S5bx~D4Z+qMogJ({`7d1R_pXI*JyZNZ$d+py)8q>T}xkEH>1}l+M?R!dozlkzG1-8xh#+j^rbGY|UG3~Hgt2kvv)xP1>&aImH z5JumHZaGlF-%zaq0aI2vsq76ve-?KGZ8&V9N*rZ!xt8BcS?th#2g?33%wKC2c5WBw zt9>6q@_4cw{c2}6q#K=dIvkcAxz;oz6BkqUn#$K=;i==&;bSm|y{TWc;Wig?N~n>e&wmg8Y09bxFpdM_qkVCEyC zt0YT(6|-*enK)c$WYBLhM7K~pmujx^2qf)7==*?ch28lv_Z+u5B13n0_e3q4=KCdt z2Eq~W2F6}SWMvn#wl`$j`o-QZ+{P)Uh+z16jw*_d)4I5aoWi)GOkEaU-hODk1jcAF z7M)jb)Su#VmsO4D+&&rJdMRapuh@WJRDjnn4y^BM6=&NGy zoj2FAoK=-G!d@KLzJYL~n)WWAG^1oI%aetyl1-3m(l1u%mQ@x#lz~GIi_B)BLmlXT z$=^%i6uYeJ4mi@DKh%TD0Tlcg<`k+840@)ICY3M`5-g6(LELEog3ZFklslHEi^mO z>5bo6ih%tS(1`!)I%A%%tJu z3~`t~F{dQY{sZYNdrR>8kvDIC_sCmEet6`^N3sL=^}KYlI`F-l-?{m{n|u0h?K{`^ z@`=AW`Js_$&)c^pdwyl$(Vp(f*G}Bi_tuGbPP~8Op}zgozti>PK>yHk-}ul@&wICh zrR$Nt{;{3DYkiOReWCBS2PQ`D7wOQ6TpIb!p1$@ZS2{h{~35;=!vmUoqc)e2Pa<}Iy(5)&@WC7 z4em`&4!$!~ANlmiQzM@{{Rbnzd-~|avtuugy+8CJOPb4QQgJ0_Tqtm&G z7tcO6_`vYz2IIq5Cw?^crz4LH_l!R?_}Ph9PQN-*9=>h-*@-tszBcid!G9llZ1}4^ zPYyqJ;pq#5w?8}l(%?Uy{?^0`!`XA+KKtE?|2losnXgTbocZ?TD}#SO_>+;hCte8j$va1X)c5Y$2S<~m&gd_U|74=;+=tJ6>*fc~yf*yS@H@lF@$U}~ zoN`CsA5NY5wb3t(K6n16vs>e5PBq5wJvDyr%cJk#`uOM(;lU`$xNaALt+IUF?7G_-n_OkDuV5S1!~K{0KhgWj=+onK zy|;9~e(ax*rF$FwXS%1lo!;li|6%mSqc0sDzomTqlgIz#*r)oRI9~0&zdP3b`TpNJ z{^Mg`>Q4^Lox0ThLjNawAMO70{!;g6dT;6)=-NE>Z=-kI((Hb<{|}G9H~LiXuXa~X zJ=godEq(vb-gm%7jkNzyvP)Zv0b!9Qp-EK&0wN*=X?7Mt#d5lyp5@NdSYGw4vFpj5 zi+X3*AXY5I4q^#5L{Zm{4Wnm2^; z+ua^xN8EDEb~^jxT7|8mj>1`iE9ThDP$-oT6@8U^l@7+9#(~Dg%Ckydc~|*F`9^7K zWMec~>1-5X9B-^K?qb~AxSkPV6k!x+)Yd4?=u4yiMnTGzDl_Fv#TL~@lL+N(2h@7G z!y^l8>tZ`#dCd8e-ByQtcI9>!YTnt(@}PsWIzSzTN2;AIlkr_9JI(wo&pCu!K5|a5 zEHb<8aMmo<@=HtHy2#`gvzHE(89bnX4#uT&xID@MySVxeetw-FlvNq=Hnqf;)<0#dS1J z(Ol75p;2tHu~&_EZ06D5rrdIswaO~OC0*@nI?J)O%Odq-H&0cT;}*wW_%`dajt8u} zxtzAHV-=)Yr~bv7a;ax^z;UPgk#$Fp2`-3Dh!tkzYBR?rO4Ul$z~-gNDMf2#sv=F% zRngumO;xP^N;TSMuqxfAnbkPeBAay8I-B{bOX>>>OXV;lBhx{~qmA#WryA2nD_yKj zT})>gH??W6e67e;-9`s0?x9i2k*FoG1hqi|K%f^Mf!s$sBICd~@DlMu#v-#3E3`gh zj3j_tNDD9?8HBDvTOnb{7sxkgUE~CM1RaTHqn%IQQnl7LhoYIv`Bjas5`$gdi#hkuPwCj_Z%Q@&pf z0%7@ZSi@4}JiHqNyMe#d3Rd~IHoOLdWvK`TxfJiQfZXjujw3tK&G6p&QoqEWO*cz+>0Itq^mB0s`f#c#e!lJ0LLaiao7h*(1w zq&^@5)PmL*jZ6R&Kn~1hfFF?VXm3Qc+)qy!AOTjH)`8QKWt~QyCE359{9zgf=7P!a zyqFTejLM_WPafzg*r)H22A~c49q5aeftKhpV&d4=bo0va?u;>HD z4R}R9ScEhM1acbI)!@CpOoLMBWRn3NBdd{k#2eXxq@x{BbJP?)geIb*Zj#_ANP=sM z#qhpf(!HY1tD#<8rG!9xK%mZcOY-amOSVGtf->BLwgdCfp2%`I&eFhspo1f#8;rfY zU~TPTNjFdr^+g>~Ths?cp-oUPcxEeTh?FBf@N7Gf2}`)vSgxL;W??Ro&id;{RjUSC?m1d;2r?UsePEFDvz1wf?H|F~0j0O`8)B;j_NIf8Z3+X#ZlObh5S`29oq^*z& zAc_4m0&+hsA=y>hi4!E~_N4EC6u${d{Qjmch%BS#vu@535y{TZ7Jn`vy!@Swh#w_r z2?)>(gn{hrm#__^I)FE+128j)f$;p6-oz4mR7jSl{8Sdmv0I@J+`59k_H3o5=g+Hv zx@5Kf=izI>!X4Rqr_O8XV++@5lA5ds=$H-q3C=lmXg5}~?KMm9AUA26@SDH`w=Mbs z1zTu0#Wu~dW!pge>)Z8bCgy?*2lMoud+(qvSLbVfOxy`#rti`h`0S>Ke!WNY)QqEF zwl2_&yjK9~H`u3Ne{>(Mt#v?ib;AKLM>wdr)fEDVQ-}2P2N%(;w;a|SO*sPSpNjP$ z^k{bFN9+fJ{;8C04DTtfcwbiHhgFL9Criu@$|w=aDixv|JeQ==W(Xq^7g7P|7E&2I z7YWU|#nhYWO9Ve=sjx!J2o`jvVAEik(0XK+Fg|oSWt6-hIu5}1 zdQ3g|1m)TGBxTa-G&ptahQM}xEEJ4Dg+s9laPGLJ5Vzh6bRJO)>(m#cVu#t#&3f0y zMt8Rb-IMGL^BUjc&^LzuyNhF{S_hRzFd<6uSUi9Q+1cWpatW>8V|lCuq3@0jD3TJ& zLQ`o!S}2DJkfuVJWIz;e(Ji_;3+vIxEW64_`t1rB?}#$)^-z|v@bGdnmy&efBr$EbQS%bsgyr@Hh|3 z`%6zc#mkG@7g-NXHTD*sx%kjKZutnKfFB)w*pJG&>JNsj4G^yFtxvB^Z@|}P0`(T( z5d70|LHY+RgZXpa8|w9bA$(qRsD6_wOncU+k>>d0M%rA{#+r?%8fzEaj?m2B+(bM2 zP^9KxvzuzWt&Y-k91_is%pmncy2kKb2Q|~TkBsG`lH)Y5ZQ^-6C_(czpTMKm&GpvX zoAcL&7Mi>tT56FCt@OKkwC2;Mx7L&`Z_S7QD@8wjU5a++g%r&M&s2k*uWhqy%(y>4 zzW?qd*>Zaq*>(+cjELeGF_L_&JWBGQ9q)n^=>Yg>2Y_iIc7xY0dYSw)ZCi1WT9;Nx z-#=d{1ZSQE%R?^;-VZL4gS}o+zwLcRPx{7G`1YVFu()k5B=)eNql+x5M?YH8$){>j zS>6~}x!qA1Sf?(1Gp0G^p5GiedbFg@{Lqr-F14a=e9@ZDo!dr84{6IVi;|dpQw_c# zNW-k^qhThDPG*jjBr{8l+A%}=w_`>&N@3hKq~HmcQkeFwQ<<*z?Qwo|dq%moJ<}+l z0~7VU12Z+HBff5YM?BRojls{QF;DPLOiEfOJnU&F2HoBnU-Y~)!+CXKVvlvj`<8cQ z*oEEjGezC-w82_tG^522M1P5U4*!zrukM9s#Pz~$?|;RFJN3rL@92Z`5Bo4a8U64! zd-~z}KHo4;e)t2*dY96&S1u+bTGqA8Hyj+GL*4Q z9me#ZF$~}8H-b5zHUf8l@f|)sa3oW7Y!v>Wd=x%t#Te$NQ)BSb!Q=3z+2e{U{S7m@ z#dt|)*~4Y5k581!liNy&FStKR!k31+FM-nm{GNwsrStKFeq3`!ne&o+G zzK%+l%H6+}konr;M+u8!CB$uhnJMMNtaTFRP?+3^SN6>{MZ*iN%==J zB*dHe&z1T7QbOh$GGEG@5HfyWvOwn3c%hVkzG9Kg=Vb|*C8L)}`F+_kCZsSjpW`LO zH{;7>KGP&*IzP{n^5eXgOZme6D`Y;)CBz3VTqWga7s;p|yhi4ek&u}fy;kOPn1r~$ zdcBlSij(o=y$v#-jyY03dIu}zd)=1tmTr?&ZoWrCJhj^vna`gjWL|}Alk#{^8MDlD zWj-5Ah-2sTWInMSQu+3rd?|nFvW(rQ?2`H1A|YO!vPa4b<7FJ;S0I(oOOue{pYN6V z4BRJ`Pdm0>%C9SzF>u8}na@)aGK&TulKEUCAs*M_u$1pRT*hBri)B9BO30+$KPu(N zI31G^>_0A*dp?p7|2E@<%;zBq8QZ?6qgt)K8IhoH`2^syh5-I-_ zJ1^mgybCg)w#R1%W|Y^Snd0*t%bs|G_c}hS1uhCV;vOWoYIE_*zZ?bAl-TDh)3*->G9y zn14(@|C`(XH@E$7Zu{TdCguM>%x$7S6orSNivP?6`4{Ik=5fvIYVl)Ow;SfQAn1E1 zi~iRcU=y9?b#`4y;=E8F$a_wGk0(r^(>D}T1D7172mE-9N*;Us?Y?@N0)83k9 ztzX&4MqAXkw%)&`t#)m5J56_gwe|-ed;KhnI@*Dz4w{4a9rzg!9W|}=PW-ngob_Wj zy5RA2xM4r#52Fi(-1p@lSrfk7%ar#yw!?m2g#En%(L+4(Z_;1Q^%tEyKB>Qm)L**p zr}g(S?5Dj8z}#E_FUAw%-V+AN0g~9BCnPUO-jKvw#b3PH^#Q!bRQ>ThzZhGobTf#mDx;u0NH>>#V0W?}zn+^$djd4T31jO#IDP zu^*xg#eMHOA}^2{h_Vp*gUl*m1169xP?0|X$}c?Fs9&&mOG#oz;pwY^_r)?8zAHri zO>&pp^YM^Te4ZwL4En3uzcG-9?;*{E{A9SuexnzCa~3tIw~e;6UTs7F6tewD{d2Ao z9~w|3L;o^iJ*!}SYbxubf4n&ho7SSUF5j=~+h=yKBfC|VpAyLaM&w^(EZ5uf`TO## z8qXW{E4RWn@*wSj?G;q&M|_-Mi^?+eEO?ZOZOp%{UGGtfog8tM|LWFNDmw56U%cjq zaIo#K+GexV)N@mN-oMOV@Vi?_+x?=0kW=iay}rvy7`ernw_oZ)na{4PeK5h5YDwYz z*dA`w@pkUKBF;lVLp-&Oyu5_%WIgS}w!u_bTtoir&=4?xv4%dMnoMu$*Ur#C9K0QW zAFi@Q#Z~IAt3}PSt;se|!2X_w^c?mbI{UZ#*Zj1IgW4r&g}nR4LO%7{VWHppBUr0j z#X9>nM}d0pQH(7<3PP716Zfk5U#3fY)mnAilfsokOKRP8Y2T7^9Eu4MS?+>Qq=(=T z;3=q_rTs?A+sIq69NG-fk+Hg4UUAs#*mzx$Q37_wBN4m#AQ3B2v@q!SN$rGARrjy| zcs`c>ZMvD<*H786#$dmLAvLNC{Q*Sr*-6!TPFt8>A9L>40Nfc9h`nh}&_;cNFy1Ga zzLn5WS8g3b7u5^Zl|Brm*BUp{aVHwlKimx0E!)_b9(XW9Hz}hDNY9DX^&Zp|444^( zP3#;EGy_TOtB4p7oYV|Ubc_YIfpM5`SsZv~m4KOFNT6+AB5mM9Rq-Id=8!~lug(hVlAj761n$Qs_*KUwPpWH*qg(Ms48^#!O z>L3&Sw?CM0FEBIBo%Lqi1wo}h&zqCa&s*s8IZN_uXU9NC7~oVehV&aB;D7tVH5UG{mV zE15V9XU~s!BYiu#6VJZ(AkD)(iISFH3!Edtg!wcOj`6yQ)_#w=*z~ogNoY z{`NSYSXn<&S*i0AulGia*sb%_F;)F#yH6QU(gUJDlVsbtwpP~tmz`z*tNH33ingE~ zBIiXE^QM*i11+mQM;cNw4o+Lz5)(jefHty8v=djro4dkz!Bw^yv5%3E`c&Es7dHI} z(X7WwvS;oaB4Kp}89xsYKGP7=dj!hH4N`EiJ(O&{WFyWi#+Wq?GU2-aV8Y(T%*c!D z&Ddf=#U0_zi96>lxb>VRaU{=*JiMkBv3@>AuA6R6%>2%V{IOqcVo)brl4@Z`q%>BO z?R@Rof$nw45Hklh8FgfvJ#u8ct~s%uC!HCSy)LZrrn=0XOjn}uFq}Cu-i>hT;Evz^ z+Jkr<>WLq2=|xF_Ka+kcfX!S|pBb>Z0XuPQ zAfuU05KNySCU{6NF(I)bW1A8}^zsg6o&|>y2_}v3+RovG&#iF$>8r+ssxSgScd-du zkB!9h@|&`zx+r|%!f5vHK$6)$DTXahYR1g(70Yf2jAKT{#S>Q_$K&%pw3+5H?`)=I!JS&y{v~QJ{Kp3X8+8$ zsFll*uXBlzhk5wW(jCNx@C!uQuNT;>4wvvwd6x*gSC{e9g{8!T%UAG*sXSXT_X*z3 z=qb^Qd&bnYdQJo+zrYU^zF<$P%9t0c%LwCpub442%84I~T$pns>awAXD|5UdPV^h^ z#vC$tXR$O7oVw=0K5FEJ7oPSazM~1IjY|-VcMQhAHf~6yhKJwnx5pV&<%6WV=z@*doX68)LtN&Dy$y z-1s7&IQR2T?)v#%tZKw=vQGXUc4lXeT)en|*w}6LzED|T=sSI-?)~ff8V~g|8PZ-zg-~B5 zmHHBYfm-}Ot^@xi`l>#@MEykm8GmMY3W11!(YMbdK2;}G*Fg874jw`ZbOTtlo4o#u zgCuTNNBjeH!F7c3#l>shN+kL>f{-u zS5Q9|?(*14fRyOv2!}fHfTV@g(;Z+#A^sEe@<;L8$Hq^uO@CATRz*L~e^NhH$Io=AkAsko zK;2w|_)nN`K6UOl=;ZWg%r|f2vq-JhIqs_H_3^7r?EaexPm13dnF<{EbC4w57k zANa7H8{dtUzjMCX{~6;Y1?nXO(p;#c)&B$?t$6)zj&Vx#sYxeH`Rqit-Kj)!*u&;* z$mSMg+KHA19c{_^ym&x7kaQyz$@(e&jCf!t)JYkn3aB5<6Yx?0>H7J^wI_Mv2>G!+ zgXNX}E&6lUpOrrD(r5TMPpFfgkotH6Y=q~3Ni5Jduf|wlS~dUncf|uQKEuDIL!A^s zIu7;2LlpP4bx-Yc$qW8QtWa*k4Lz=656?B{UT(A?-i)v$>(91ggF4sZv_mmAwwEomi(0&Sd|kE=1DI zy4+IQm7PH0%2W_kYP z+O+|!1y!FbO>e+HND3rv1`tHwupq8M$6$6-t%e-dD1A)tYe0Y{Olh+LoxGlgKxehUnimndCKZpP!1d z{JY;z6`wT+wsLA!K}y0w=wLb2a??y0eQc~@UD+@w%i`G_8p3Ruz7O6>bhVcY;Q26;gCkb z_Q!h3bE)$;{|5Wx;&}dLmo%R78FPGD%e#I|@HhU%RxSYF-@86BmuY~nObGnkeRQ_@ zg0}dq7D?}q|IbL-mG5p`{QbT4nNZfpq0D)R;`=4k?QJXg0grOD9eQumo{ZhD4YSA< zro7J84!V0p*pg8~QvhI-`UKJHA;DPh#D?^Xb|F}E?@;ShJT(cRcTT(x=a{;=$Zn z`T;{R{@O5Wy(ZO0ThYC?CW^4F>fg<(>bFu?PKRn9y9QlFz_t=$o2?*3{HSrz7mkaM&jrqWC|e?D=l9`6f%3mL$hByvw-Ev;hs4@fF>&(ll1f z`KwVY(t;nX(7y3rm1cWvm6kVIllE-=8tvX&*(Ek}*J_s+t}A&mY`u2MstqM)JLG8l zPGw7S!#47hs7)mc)SLO&=eQM?94IX0 zGmxT^RjZ2lAy*Hl?bjXQ+ZPn4t)z}>FMesF(dU_H2lc3mYvWsCc&AOX z{zLyN{=d4xb`A1PhjJ~1@;wVt^yAvexl1&cp&!3C?TG%q_N^bcXx#L@_m>R*+@Qyy zhikUYs`0{g*v1`5zrpq%)sx@f;m2kFEOe}u%eH-;OE!C$M@%T)LGBE{K$_mW!2RZM ziRhDeiS&4NnYg#Glw5uJ3K5gabC&bucx*8Dj191QPDUh4@fgRe%2?wyWu)!BSL}=# z<>aCw7xu=8x?C*d%3f}Wlf%cmv1iTQ#d)2Wof}R*ywaF;xzkwekK3onyRxr%;qQ+_ z;0<^WZ-CYJmYd%xV%7Q@!+N4&eK8O_iMnjQ za*56^e<|ZPh0#4NpweaX=3vix3*AJ{ z5@hCCVa%FZVB&lXn=suPeD$3T)~jD_kl4ugAVA76Vq-n|Z{GIOB4QAb_9 zM~<}FH7A|vNoV@k0vFxgjdkgxnXZ`2Fr3aA?}k;hcL&8^dtg^XJ;8>SUf4dndO+vr zt-JEZ8w^(Y>IzDILF!#UUDj@YnmQGro4lkx-EMOOU7xXmbjWPtQ|B1$!NCZSfAN#& z80^5~crd#D+qj!^R7!T=*{WHz~{nbpBMk``U7unh6{&ZHP+lwM*LMBez+g>=@GTk z$XHo@@K?S%25O28L=@j0`&c|%JysBPwnicA>^#(ylMlcGd;s4CUK=v<|G+2KP4ghe zUi08UxEFEev=`~(=FL9bCG8^+^XK?-PIvuS@*9709~VHJ>|LK+!89PYBm|OEX@c$I zBCVl_5ylP4FTh+V}~6Nd(YQK%#7eHi<+>`10%_$`PE!ZDQ6$gg_XOl+4?RVpaRz8go_HJuJm*+$ZKjt^3OJ_z2)WT?*8%R<= zOp2kGB{ic4_KKw^1;$ayaq)ETS_xD`&qOfsMIvRVYyrM1X+b^zr6ovwKc)ueBa(!3 z=^EO*N3xLDza4EBlOil^oeC}=O%>(mC#_c{Z}tgMitO)JZ}|N+VD)*h5X$8-luw0^ z9IHeI)Scb@-n?hjtS*Vv8n2FT|F^?&YCkbPk;0+M^(I-lPngTe7+3JVE~>^UwR{0@ z3(4LWV2-|(-wEOWBtzWiG1yDh_uqwM@7HCBWet4$!8!tAT|vHbJRts7_ZaA~zlN2F z|5QZ>td!QywAB=by0{<{3_Y?;cs?F_qkL-b!F+J@`c9!VXBRlMf49KR+yl;b=BP-v0HjaaD@;n- z2L|-oFZ2#PK!4xnpwPV5|6}h;z@oOce^>+rktnjGL_mg}VN(PwQK4)qLB&GV8hvh9 zlvG8ur5In`s0&eXw-|S@RzOtnsTg<#Egb)a*XCR!Z-gK*|Pe&Fz1Krq9pud^fq)S|aKjeD;v{{N!iI)3=--Fys+5Kvcm)dcT0oSIL*YsDw((AM=;;s-R0(s)>?wPe?B1 zDRFT(PhNjuK$Uk4o z+ho6lY%*JT&7@b5<~E3bx=I0h8m&n5`a+4+n5s-X!FrI@s0zV~RY}o0RpJ=j6WaGf zPa=U=CpU2#d}={2GK$gUH=gPZZA{kU7jB24g>ilO2}}Ay6T-E5x3GSYo4*ckI8+xh zw9+GnnCe4PH3Pyx(U8=yH6)r#jL4=OW8(h#{$x?w0OH&p6G&?jLhM;K5UL3=<Got;tOH@O zNenHT{Ojzw zZjB4KJDDf7k3pUFZVK~!Io}!ve0n$#9!MSVal{(L4yfxoNk^M>w>HwRHNFb()*hnQ z4@y+Yt1LcKx)o?|fh-htK-9BeJCSB%!J*oXTM?t{(C=!4tnYGc?|ZJgUG zVo%Pq#4ki!u>}{b-dC@1PU~E^^0+t?+-m{2XSB5}#u9;fJ0Xw8#Mf(j#G5&1YhNb_ zxWc%XHg;a8X&=MC0b{NNvIdO5&RRBaO8Dx(h*$l|d@Ahs!(@_1H{@D$>@aZYt?fS#^3;N|`=IOAM$D7Y*UFXN=&ZM~va!yZZmu=O&29 zJQ54~|B(Hj8aPpU2pU&VpKLO7>6yd_3WTdL=j>Q7 z=vW^BpTC}KMgrTV0m%S%{1IG*y@T}GOj$k2Fzz~RF*O&d3AqDTB6*0!^)7q^%12J< z6u?Kh0y?MV9!xQXbb4_SbtL&dy*aCxS|9g-j!xt#BD{nSi!G(b`j^ojpFN~ptbRs9 zeaqqCzK;-hQ3dQ=TY(s>R>C^Dl}JnZW4J!83gNC)!v!0j(9)Er@aZpjx;VauI={4* zW+LmTeN&#%dxM@+E4*IN%Vl_?XKFRV%hj5YZyK85nH9~*jC?8Vm;Dm)&1`|KlU^ZK z+aS2tY6V1Nu_9&pg%T~As!Z_;J>)iWTlglQ4E;CalYCC$7you1>R7L7pN~p_t_^J= z&cqgi9c*RsNcg=4;V=ONd_e*TF61)zgNdZ->D`p^N}Bv-#~!L>#$HHe`96yC*-svf z-!HG@2tEcS03Qq0YJ?W4HT~+kpX<8+)%`lD`=$0$eyiR+_4mwY9r9Yjcb)UO&bVm% z+MgG|l{b(BK)we!yKF1tRr7#Ew(U8aXnJ-9l;F9Y;8$Pgn(W#%>dU>G$hn(4e{y{BcdwD z7{7JCKk-xA06cAv2@fqo@J-7G@}(iBT*@3X{*tRXw;^Bp%s9O;S zimkXImDa?noP9-9rA-vv;0(@>ySux?;O@@D-QD5g?lQQ;;O_43Ft`uy?(l$+WRXoy z7Fm3Cs_*Sy_G$TUSJC77b`7P%DmD$mly0B})+4ojQaY73C()Poca@x>T;(R>eKl>y z@-6WHo^9Wop}_P;QB>jQxqDy^iv5bnYFUWp#*EyPO+%*oFG%8_YH2(b{|pj6ZTWq;fi0ubx7)6$A!9YSd19w2U+Wdsg2{o z*&rZ4LnmYEPg(}Hh6`MA)K{pUOK140#+HczE_#7-X%zG5(YxisjPb?62aM&MXB@}+ z6T(Nss7s8gKJ!)gIZN+9=%xc}h$kVjVkPHnDwvF#+WrIRb7H62qhQU^7NA+w$ z)moehUS&p6hs-V1Tnk8msCSkL*->|s4|(YVhU+BlocFNo(#corpPqsgKCsJ8;oJp; z5%^t=@pS8fhI~|r2Ms;!!#z*z=hgyfLU&i~m8jSY2r+hGHRqpK_%Z@*Fk3EdQGLg! zqY=1|Xq(ABKg(6iyLfX3topd%z31_;<+%^l91biSFuRQSVw9YK|Da^wKDSR3-$h7u;=E zJb@Gzfgi0S;Ze^I@*J?Y{a`_t1jGs_$u80rBz#XA|MVmAk1+Lvgoabp zxvPjQ4r&Km+D@IB7#^9)RDoB4nP5*U{U~Y6*v7~*F*keoCKsUBPwr&S9~-TsA(gS# zv7?)pD5~zW_-t2yDtX?&f1=xG#X<26etYOyqSp7EX}l~O(=Av0#WhGW3kK5H4^vUD z8>OB;z0_&J$N`hn;j<1S)Tcf6_W`Rjx(|?Fc9I zy7p#NLJ7Ik_Qq#~1Q2>rzEJu6O0jx`{u}Pm62v#aVF$)EnNupep_}hsm2}K=lCy`K-_5@Yh9H= z+`Ov1@}yh+Te}7)_#Hr(ZX{x3!iHvY_u0&6>}s5vWkQ+!;5zQbb!mr{*W)df!?sS!CBSSpRXSx?myLpC^Hv=0)N1|Tb@sUq$>I)6j=1glkaP-=u zvdfpFx6@D4=jd273J#RyPXnudshSStX=Qdba!TCUJa{iaYl!*?+9M3N3JC6L33;4{gy$0lNm0lNtD5Ik;Ix?d`q$v{@d^{c!et1Z+H$lmj}(c>5`q zSo3sSg64)*qC?5C#;0}Kai|x*ROOMiE<^S8j4DuxHex{whE^F92^DH&T&IW5trfA; zqQ&7gZJG@94-xIZ_p~{7AL`PBZ;8~~FCU_`2_hvz=!po~s4T^X5>ClXBzQa}u|40V zOwN5PbT562+lE?Y6c-G5Nw<0{>S>A1Cu;g&x4M*B22CVPJ{02myD6cJm^e+o&$m}J zmAkNyfJ4Fw+KS$@52K8mL9)r+!2u`HUd zCVm^Q-3^Y*X>}UmIVo#eEcaV3>2WP-v-gt$mlS>55CmYo&LM`1l55_2%7-4Ew`3$0 z7pYklFUA0fi(LkYE9v5hoZohl@dVegP?;}X4&5`LcaK@Gksu#=uxC(sQB}OK|IlZ0 zmD&n4!`FaB&8QN52H{4YgN2s}=k`T%j*yEF63)*N{U7AGn-1PV+>VDYVrgIpEl7_P4#yz2!hCktW@X<-qL$IqiQJ+-7#E zym%}Z#cgUu+i`BGLyPK(5UZERC}`)0KYW}cW#+0-NH${n=d9d}wKqLa#?IF@s=dZn zrz*<@HwPg{-VJm`@7={I>l@EI%Adq+yfZsfbiSg8LS>AlY?`mjEV}4>VlJSz-_y#0$f-8h;DK814Q!O`*cBXBgJd9tfYN7=h z`XXYsHenhNXomv@4{-#kPIx%i&!Ge-3UU!!LGj~>U(%rGIRiVtm$-`+9ijF`ud8#d zEbG}y4~X7Pc=EZQL0CNFzG~bcAHQ)c$=wB zwv{@ZBd+v(Juc>0S)M7Ec-<=RypVPq*R0FHl_G=Q3XAS=4%Yn%T?X0vep`eFdd(H$++lS&h*jtsRCMH}nFY%|OaFUF#xCI(+X8H>SErBNlZ zn=4XnT&N4~)I^ZJ7ID$|l;9HHhL0Tl)+@)92K2KLtND|e1GhEXhS1gMr%NHyeM%@J z-U7x2AAm%acLB?rvW&m&W*USN`8K4>2f8o@8B9Yznf!dX z$&{7_o6AGg2k{et0KP;`F@yj-eX6>3XzvGQ{7&p(A2~H}Uk3WbYXis_gFf>x;mo zV)Nw$2GICr0i#l5c-G zGUDcl=ph_I5k7Bn^$)z z_{Wsonf2u-?r&tnr?;^_(ER*B-djs_L)Xjn)_fz*6i{)Wo=G#Xs4!2Ti|*5P7%M9QF(nRd+6X zbOPz39A5vJa{(JF+vRQS5KnA)6SRMM!0VcR(CD4U;c=b^yFG3T?(WnJwULb+x~#@& zT}$}OU{PZwY+A=@_^i4$_V&>Ep#Sh00>jh&;f%4m&)AmvCH!)nahe{1b$eK}l3b3Em@%f~VcHbizVt!4QkO-jstD z#U&J4W>U@DjsA{K75awrZ%iK1cu5?=WM{nYV%EA3}|!H zBZN!nqmE(8N_nIGW}T?41^@DD<`=gAGsv{)w#?JKhLP&!7jo8{qn?ytVV6yPg{rcd={UM|deg748Yucz%tb>F7Y+#u7pGV^^8)K)_`&!zVc4b*WmD(Lv9=rIjm4z6WN>_1< zbGDerN;Wke7nr+bDH!qFXpI=L7&^bTi!pl3zj3V2u9QVwyqb&FE#mf}rZd+#MsxgP=P<0Do$^m0VGX;CH5X2Xhgw0a-6K@bAl}ws2 zvZvtVnW{GB32#pcaY+YA6Mqx#ZzB97ydA^!h`BXL0{=)O|KOWMe-o9l?-6iFE_6Io z-{hQo%1)d>cMQ+i{ybr@Yc?HVXHWQ`qZR)NC~f7fwQJS!P$)X*2{^l>y~Fj0X$E^m zHLd2OjPN*q(#70cXRHP|IyQ0+_m zLe1ym1UF1Y22qofUGFXCwB8eS?0p}cvY%p}-Ea|G&+tp+3c~KRq$bwOS7F$q zMAM*D08P+@(RUfNtt$Yx*IhnF_Amu=7X3^~O3SOneK^*$hE)QS-A{b6YXiE=1Z!q}rArf!s(n zt@S%1V~=4vjWemrr(g!nO7Jv$hF%`5W)Rw)9rCKcOTmqa73J zlE*nExbJB%UD!f%aJ9kH3rNxz9N*HbB{9M$+wSs0~zXrClOwC*xxz3%ZR{G;gGimAL+?NRR< zN|1U4rckutBL&FMjc9I7ZEi~!d;XKq?ZNHi_rNq+q%B(BpSngxO8I39x(WSU;%ooJ z!m-Z&1RPOC+VnrF2l{Dh!!5B^2gog@7!-T1cU?<3;)zNMg!Bn?BkTf`*`0+#`cI{I z=TV7Mv6+sIq(v;RY8eY#GB0bO5@hw4wTEMTKhCEKG)~Iy0NxxGY8k$l-%)FYpvjvi ze^va;jT(+!rzQ*^3@9X%<;B0bJ2P26eqN;-`Zj8z1xq#X!hZJzFVR4Q2tFW7pyJNT z>;~6#sh#WL;2G$-wfgP2*Vh*z)FumVg&SgI_lD1Da>bU+p)0DmI@-N6bbC$IQ*VAfZG{jjQPe~(%67x-S<9{YB{ zzEz>#v5|0O0gLR?o+UboFt95ewvl>0``;rnYL z9m{rMQ~HUf{*mcD2-)}v8i6P&cz!3AJ@rX}s{~-n{66~#FjoNlosJYPqQ7CX*Fqs$ z)0R$SY9Phjav(<}vXR$qr%Zr;YAwjoT$gHfYorJ({)Eq4>EX!fO*#Kyq3A<>ZZnvF z558K=FMJMP)c+glNyr{>dUjsE%J^VhXs6zcJGElis5g-p}HD922-Mvjeg&{ImA7k$0A@@el{YA3| zzr)RS;rvG)*_E+-jcVlT;2RX4wSENx4b9R4{rvm4G?D#h;KHA~jK__CmFcR(xwSPe zHhv$5+sGzV4}*{fkNeIeAH;c;UaG@Lot)8xL>r_dsnX)d{@b)YY*u*hH(8f^5P6p< z!w;+F{CuuymS)M=hk|KZ?iOBEcaj?d7k6C(GPkupYd2``zeO9K8w0bDsrB}e8fFX@ z_WqrS76#CS4>Q8=iRFCk4a*P2Mc_6I(K22o6RTuS46W#pM=@^8s(spLlSe5ks_0J( z&CnuI(xELV)P<9&{>JlQzUVlmN`X(yH9kgAP>;(=9|?06V9;k~&bhP$O7M?p$GsIr zNLMzJK4&*#;PbyWHm+qIP?){lOxnWvg&rR$`>h<{z9ag`dx2Tni4HGzPAj$75!oPr)Qy;Ni_Vy?O4p~(Q8@1{O`TT%K0%u|C2iBU zi0%haBJ2CM$fzf&@xn6k*&)1=FWO9@r&jOhR__r^ zQ13flUbxin+S&YvBgK#RE_K1~_NZ+rjvSvFaQ`^S(-k6FSVD`bHs~yBUFdXH`OXZQ&yQdnRnoeA!mC!p z8ah1cn)+1J+vcz+@{y>n)YXWIH9L9A5AyuD>LwDd>92?=q*e;7P|lK`CkK%@7YCV0 zUUn1A7JCIR9p9-K;1@F=77UXCw^-hzEWs;fDZ$|r5RS_EUP0bl;I1n<^Idpp*G)eF z5i$XrFMS9yS?UT$A$W@8mz@f;?cN^&Jak}{S<;pN*p0h*WYDYBO1`Y%(GHn0SSoYquBI4VmBDJTk zG{c%H#9rS?J>#1>Jst9Evi|KDBFZ<;QnIJCm7*t}36VKT$T9u7X=QBjbfnKwuFLbg zz@7U46f{thFT-Q&@35+3?nlRhevHqY^hMOs38UU)A)up4!gTX}j;^d0KK?zM)opqv zYJT2Q{;FrMqZ$Rn-mv;Xc@xNTKx7KIe$$0so5`v!eHhHoZ~(IL3Ez6LuS)Psfv-w0 z3r#6}R$!~)@$K$U8q|L-x12Oz5lwa$3Jak zDCsl^dIE&Lu2$vgyDkab9KW*t!cxvpuFlns3(m!ooZ|@K$9~>;24%x9f~Ye+1?n@2 zieD2aUR%tO7mIG%BZ;MnX>J6l1lkG9P(>LXj%Qh<3T;@}*2@p{?u@#sap7IBDN88L ziI=)78S9j;0e7{Tjv4As-0GSx1pz$YH5-s^SmAo#s&5Uv40ZdFFEjg06CF901sMiq zug)=v0&q*fLjFY)CG$f8bvykm!JAk88v#Lmd`wB`zqknW_ zm~<~~H8^SXbfaV`IhgiymsFYVy!bUF=%%D&=xrtC%)EoMsnhA0v29FarO@tbMu`Mo zyYBEZPW`ztd}~R(zGH#9z0DZS_RVLy=xane!DR2EHjbwLmWXi|$kqLc9|auT4MI)O zl275w|GGX%1TjthBjTaf@}6GJV>gw=tw?Nby{K!EE0*qV7^QZa;d(c@Of2@|FyRJo@~4Ah(8tE}#S^y0{VW8+;Zg?Rm#EvBUkhARDj_u*dupfdRVTH~c{| zOf|s=6(;k7Y5F#a-33B;WtaBpn1Zq{u}MF7vf!QJYj#_(Ry3dblUm~~7FzRc?`b_P zJPl|9eCi%XAY;4RxpNTyE+?Er4Y>O2mmgd0z4;j2eU?XBu<;eY^Ra*Y2%mL;_>1%h z%{PxN#-MNZ?F}_?ajP!&)C1Gj$lMUHa2!`K-s6HyQwJ7~<0OTDxXzoqx$7s!GJHbq zvcwp;o}QP#XEriRp0semhVd*kYZ}(6OSv-DF6XWL63nQlI+H!?D}FpPgl*jdcBzQV zx)qK$pW|ra>?nk`4#!3j56GNXbjV0-IXrp@MTft8&O(eB(2~8gb`}+>ABd9MT#Vob zm2m?V)Uk*h^JIaN>1oXF-#XW zpGBK^?Oh4QC{-{)TLiHXSq#~{#!IEiRG9g-YXQaEd{v2c)EV2Uc17xFyg%`QwH9St zVM2!yIj=YhIYk8#lCIk27+GMaq)dMDujv-ckye8}-(en6CbkB0ogywdlI>#jJeMSQSA?imFfw=7idWad-9U!_@TZNG++!QrG$?zP=W1{hRS^4pFZd_O@FLjH zX}#hdRyJtHdHb1Xcb}uuSiCp;)9?GJQo|_n26@-f zb-t446JE#wM#UC`_2k%PjNu!ThKMjKzEjf{xyD5Cvg(3x8jre~=I*kR0xQGFmj{JY z&^UW8#W;l!@iQ712345}vGPRTk=JG<+*|v!?%uHW7}odn+A9n*uGnXxv2Jba4a(hwO%HBgE4J}}*! zivpbNADtuKC>*U7>GL^&6CJv-f4T9&n?djXKZ+ot;IH$)tHMReUCVAi+a5EjqH?F! zZ7%+6%QN?@OMTv7Ms!X{VJI(M$db2cYI`7Q^?z;`AaTH)0CBPYURC9fDkzOF zDZM~4!JK*%Tk!8ut1gXYmJbiS=)HoZZ}xV1Zy&7~dw<;3)iWL1z3U7R@POcfZOMTm zTSr6l+U57XppAd&?(z3%x5K73Im5_*Z|e_nn>uAHZKI!@0D>kmBQ!M3OS zV47mS9Py(pt_b*g(}jo@o)F%;27fu@+3u43PIlVAYKHNgAr#8+Rm( zilqeP69S;{yD#(t_j<{xLpMZw7m@S4iKS1zPsGA z!<&ME`dXoN1veahHC)%a39?>tncC^%WP8%bTN69k{b?%q{1=D8|PChm%z*<7gUw+i zqS$n=4?_|>3+{l)VE_LPl<4dZ81IE9P6_Sl9R6E>@xRdfsjE7=OvEYvD^@22CABWB zE{q}Mqv6_7yiO}kf#XW2oQYQbyc1IlIGh^((tevv9UUbb3}7fMv94S$ZpBE6nq2+c zq2ZPJ7a0Y}rd#-{zd~rEcE<;?_Z4v?=OEYRC_BUD>x<2;b~uahOPsT*W_*qQii7XI zgICl~H#tuHX!ffiqOy~6tm~%PO!v`3BO^~kdlbW=Zr+yzKuy#-rlFc*q?yIBq~AC& zTL4DMZEc>#%OTblfgTz!hKM9#9J&|PRxrzeH5?IKt~$WI>Ns!*~2ldxv+OYWpKr?qyn#cV>O$Bz}~sW zV*#$<%%R@*`&tt{`!V@p$Uh?c0F$&5QHzBnD z4&x(@A?~92<00GC z8`O?!}f6RZL()qiS;xIUHtNqXCTJT*EHmnEh+oXZV{Dl`1T99zfrf(kauUd zzsEA2V7!#(B!}F!`^;&yVK<=8e*Zr(897M)^f4p+F}4{d$I8Ljcn3pzZ4dTKhFKY) zhwOgPJCVgW)fE(fKUM5=>=VnRL(Wu%{yic#P1~`yf7Qg-9icKFGf(2Y5hc!QK0`RK{= zu`MiFi3c-BRcNUx%&)p;%gf<_g5z8}?MWuP@L-Lru}tlI-E5}23*pIE(pf_Nu=}Nq z{b3FBY}GWl*~V8tti@u|@A&S+`io~g zKr?r0?Za#{)wmOx%H`ys=TYYUgMt=KW8AmVDR{zbO}gM3uw!W>ez)CZ{oybVycN33 zJs2a+Ju~<==u_1dl-rgijCnBie=qd@KtHdCZk231E&h>f1y{O4*T(R7mpQ#m-GV?5 zXqtn`HVjFF%ym>k=%un_d-u07*3q-pg706bGI0N7pGhOUqm_+=_e`lZ?^22LUU;9I z39-Bq`pD5@1Eq?ooJ@`z|IZBWu44l4K**r*87vwS%>NF?G4DE}TwwjbU=!>+`~M4p zspq2H_>dmI{%_C*^PTuV@V~nJ&u0FiBgz$6KLN^>u)}ICsd{ks>UCc6=SfaO?)`t= zIe_A3Cq>(Z?KWV{2BYnMGtH(8ShatW>4gvZZ#zHwTLZ)pOj$Q_kgZBzqBbK&vt{B<0@mR5-No(!XB z9A_b1x6jv*1?j&0Amrj$u_*3v4XpYOVImY};LF{9hm-$4tB<#Gwi zln#b#cw6_$>saL&>pkuUlaK4518M#vZT_d%xOy;k-y9E)mY=q&Axy5Xm{*rZ`Q=+eg+RmGs>I3k!x^m^6mQV!>`gD z|9l|LeP`T!P%SWKbglr*J2)m0Xs=gPSAu<|UkI5j&lqqR4(K1qLGB+jv5T>uAwy|8 zWl`k@|3Qa8Du}dT2Hx-xVCD~$2-r`r8V|6#znIj@zMj-2SdI5;Dtu8ZUZ#td0BcKGW=1oq<^kmWS*)k zKYi&j1G{liT`s9C>N+&0@Odu5k1pNKCR#fK=f$t4k`4)p)pp0_GDwWJvG<|wBs|&r zNdyfW7Srlm?jU}O79&_DgSS%pA9c#I9vzkZII@%{-gl;k)ulr=my;3cOB^nk+6pzw z_XQuWGa2kpI)OE}uq0PKLmfufmJAjP##UP5!n6fZU{*`u;=56h<{cLQhWgl2NCgHKR#Zdc+1h?v3+F+t&S$n2=%7bn6`n6Q0spqsPtsNk1 zsP+Z*FzZVzMQL4=XQ5w7os8ujUUVsiX#V5%Sv3^x&mtX57GvA=HnZJ=+f07PU~& zEU5f}{30n&O|OZFJ)3v+m*$|uNL=ok*(tfk~7KE%HT&m%PpqvH0VTp7t5`B&QLY{teG6j zb(SfMRUlcLhs|(8sp8*^p>buJgNJFsjJhkf4fh%w1Fqpl)!>-5fGn4DpB^O zz6e543TlVPR(cL_9&$bJWY$lc`v(g?d!N2Jr9}d4O=Z{zcd|0jv zxS-JDer5}CSha(YfyE^w$01KRj&6cDa|-eN+x|rAEe1HRFiEmw9v}Xtf{#ja!q_Q>c)UANZ3B?k zpb4lrOMQFYC^&jvS?PIo(f{Th^T^4KNDOD7YCBx3cAR#V2rE`Hp>|(TfiB86E|fK0 z7L;{VQH1sS`;-RWQj;t|v_)Iw!n9%lJw^p*2wfSrW@djasvw1lAxzS!l}gh^*| z47tYPE0}&GZIU3f*4_HIDPejw=CWe{AZaMIh-Sh)7NbD@(hWQLVWIF^ZAfJSrOZe>e)W?+jB0eebxZNz? zjg1EJrorht_A4&xB}ENyc^+p*h=zzgtNdz*9V_bWwW7V0esvQUjL#>Fg0Frx3MjCX z84EBRgqFi#xW=F+T?6%f{LhaaNKq#DII$2sifl1d~gZ6eA@equ>?7etn6-cR}6}`AsdRHwF zL7HjOP{rm4s}KsTz*%s>?D%SI911qzPcr#Df$vaov<7+Dav2m5hz%jM5Pm@FGV_N>xHRqp|`1`{%d56RV?pf1+X|egzCeCn83m7lZWZIayPx-3y z)Euu)w*E8gk(YDZDEPAdrwwuRna7%&3+5C9B(vUjft(jSYr@9F3d1*93luziesz=4 zR(#g%^}H)K(3bYimKhjV?A-QI=F1E`)QLI-g!&jqQEN5i=EgjuK>(&sAh@Q=$GinQ z_kKgUfdT>qTekkAiK?Cp@wH($4n&N~VH9haZ;{G24W|#fOsvm>@TPVY6T;yW?g@l7 z<%&!{JDUOL6iP!JMy^-j8 zr?({@%FV;1pRwCh2}ns;^*s~Oucb^Y6et2ii746VT8e+XxYM%n<(Xr43C4HZ!= z{khQ+e$ObG}*R_`s@TbnF9I0g>rzr;se2JmFN8Jr2|9PqifrTialIu_|-dEwV%|E_Kr=R zevR=5h%N`fNNx!;R z3+1@UBb&Kp6{>O7Z2lN!`!7;mWZl1o!I`eP$VR_4+(E(F@Om77H`kDAeOn~NUW=!Z zOebd^;ora$-#+-P<1Ji8ZVirf7paZJQ{MRHH#%H>BWIESduC#lQ&W%A&ThBj0~(Tk z|7Y2LhLSFmPtnyZ*x2@%2GK9f>sVLTy1XFB^1cJosE{OjYmL2ZyS4p z{{_rD{K`!XBz@Y!{$THUMnCR6hA%PlN;PiRFmpT~q2BVhHNfR7@3=oc)g`Jj$K_IZ zLa$jldT8DUhK=%sjq)Y-4|AHid_doLo#s~UlBzZh`C6Lf7T|2|*ruuj7x1^b$7bR9 z%#;(<$f#l0%(ee1+o~HTJLvTR3{~^l^t2rPf7|sxN4i5b3qL{Sb@HNLU~psFvbyi( zEMeWoS&I#jAUn*cU(5Wnmf88T!YCM|Ms+K9jV%VywgTIi zmP&%3#7p~4{fy#J2Ull6DkfIkBdqS>BB?AMC?2@7G4T#@= z-@WI|6W^*F9Bs7%Oa04%XX^(6I_VKKEpjnuf*yb1koXE(Wpd_WHgxAUZ8aZ^qwqQ` za`-y@gJ9e!*U!}4V-dg- zO&5AW8o^K(i2^VTCT{7|5w#73jcM+$4z`Ufs2RMm7rlUOsulPwYlLXNY(Z;34Pa|# z84M-Y>`=MKYD>%`Z&$tD7m&I}QIy%c6i2E{R!YU(j`&lH+<6}OTi*g(X6QU*-UW96 zR$84q&)@1ZLmv@)%IO{_adkbf*Ggag{uJrR2{(PVcF+*9ayBt`2liborwFEc0xfv~ zK4i=t4~%t5!*g^CU}nOwEP_`V-gm#u?&ikcj@>gwv|Xg)6$@+K?(C!7Uip@pi(MTh zptCoH5fJ|vzzLDt5_Aq}KYdlRA)@2oowCZ!nR9`eCp_h`At89TsxXvwMH~&8aj}WS zmpDI3_#a;3xzuix_&+|DDB+cde*r#(5D$e{%jHlxskMrjl zJgF4`EfU{r{7TAB;)0W8XbBRL)u@MZV@WZ(3#)dz2K!GiEP2P!=?uXb3#Ru)9S1yZ@P7N8aUt1f{!p$t5ds529G&&RJ~axTX)u=Wusq2N`9AR~e0R z^D4rt46UIL!&x|a`-24+MP~A-Edwl(tnA+n#~((;Cc|PvEdyn^B=*iO#OCSmEP|Fh z#NxWV@#4lVf5Y|~kG1IhvgrpBx$!~?%%gW)@xtVr>IW4w*Xfo$JPenukVYB#ac9!i zBkL0;<6hEL6`~xFc-YGMbn6V3+xFJrx6qp#H=UlvkcXSF38RPH+hlGoMZ4-tuJ|z{ z+ky1MqwG=`s*hgu|1EUw$3IWO_0f`GM&_s(CuT&y2ne8Uhx>n^32N2)zYDer__FG? zuSg)dj?v=_=L{I>RzU>)LkcLdaomCMvN&7P-7n|$%4n&)TShlcEuzZ#DE}`_^RaWV zyu9|w;QkRnfJlIGFkz)N7Kamj8#&N| z8y9KzguwRgkn?Etod9De#lv_+Xkk==;4+5K+*Nr~YZHS@+b|zCH*QaUzr$!M{YtJj zKfVra(EH!$G-7>Be9Vn&b*|P~QLd*chK)EtKAjz5bo(1GUld?3n9yaFxP{}NkI<|dx}rs-F6 z#+6_|A`+KRXV1)J_eG#UL@1DWLMVntLMjqd96-Ov*e$CgNvaUS4t4)F(R%sy6jbTg{{>B3kj@K3G6~da1N{z7Sb*HS31qV#;Kk$w$8`!Km=)x4mhvl2x5egs;;baPd?FA@haR zPpzsxd@ONo!z6VwMPzWp#(2nzt6AKvZTx<=Q$ z;}k%1YRV3i?gl1KZqtn_bOp*{BQ4^QJ{s84` zC^J-8!RlC`(M4n!GyiiDEN2ll_|83blKgbkKpLh5TT(0wcfHWll2_%YQkX?p47hh1#EE8pa340y(AT#I&XTa)bDAda*plXwTf%%iPGky$ zr$fgo{0ZrCZ^`G!+Y7Bmg%?at6@)i8<9|l~k)pCw{5K*CO)Ta3gB^ljS90c9<}ao@ z?(d%Lsum%|14(_;t!(%?1Ka4aiQtqm-1GM_s}+R`&(L@NG@Lt&2)c8sG0(AhT17AZ znh$OXfzKDhn+C!;q`s9aDeT$&fKu~c__n`d-|59o(SFnEIB|F!Ee5zOa&!dHE71Rz ztZE}q^}-m>DbY*y>A;w@3r`&*z>_@?=t!NAulYSew9`xLkd!tqJChde5!5*EMzr2$mhV9~~U=-7(&E zX7sOIj}!U&8*rb>RfG1@kVDAWv|m4O!bRo>c8Qt7`)sP zT9g14WXrfUbXA0N!WWsF!k!YXMK2HgaRYiwIYWF*=kN;(ZkT*E*Qq?G_g9;s_nX^f z%IvS+J4u>Og~)2NVZHXQ8oRi1#!j+d`aA)=VkDN=)LQR4uZ7GhJw*=raRkZsD6%9_ z-ya7_s)&XNeJDRvJvu9zG0m6*imb4^8XONkls2RjIyvedwG_&bGKx(^Q39ASf1C&s z&cHtPA7Lz*wc8B^*C#NGwOJg-hp?2IhDZ3#6EEqjhW32{Oa38M%;QUOpEYUIT+HpD zwjRL-xk05nmmKD`y)b5HHFa)-YwywZ$?mySY;~YO)36szFi$ju3m1+q5C46-@N>1L zkvAregV|UOE2oIY=_C0J=hMLr@{_m~6DxHs7lGSq2-508xck~%8ex*TOx6rb5hCSJ zOY#z;59WL!;KEuqBfhC{9((Fsa#y<^oBek*s7JQc-wpOHt0-`a)O>l4~9%Okj0nx}P>B=7Z;z6kB)> zWV~z+l>CM+B*j`y&^e8L(1qJo&^{Xf$>ex$kSh_Bj-UdmRQ*HAinK4}Pu`vfd>5J= zUAp2?>(_a-yAR8FIDefEu3sowSW?KkxFMJ@U1$EcpkUBHyIbm-n#n`w(fy6I!E;CS z6kl_Qc6^Atc5J9yG)l801yH8))4+kram0EZc(*F!@L0gn-%!cMvsaLEv@8*aA+iV_ zfLbbGr3Kq;!$%{)XAA1NDmIAId)leU_URaQc&J+Y@$9wm&1<7I2@u~*S^StT#r{tS zSC~&?kR`UQTO$A=p#E?ba6-2JuzV{WU$%$ecs?wa>h^Qr#yhk-G?n%JI+fHNriL{r zZ!*Cl!pZ&jmXr9l2QrE+H03S+qBit!+O4ync^2JxF} zz*qTdh_=80bk?46^mQvviRan|lEKn6;l}4&?&1QWf~79D!iWGSTdY~!5HJ*tuzMvV ze?jjC*hF`GZOUbSkMA*HlnIj?c*~(j>KOu=!MmCTv^@)sIlY*S>pYHL-AVork%KHD z*URrBtmuCLen5f0{z&8Q0JdXVAZfTNh*&vBK#(eR>c_4P8g zTlb`bOeV8j=JTTqE!^xXqCH2@Qhh&Bd8MCV_C5by${0lJRo658z03{Xvn>Xsjy<>S z#~BRxumv+=Uq>P;>);-U>}0qHV#7EI@|mSKIZwjxfgo{nDVb0!CB3x#NWXkP(xSqj z9JDt8@yrV(yDSaDG^dQ@>Pc@?FaN!VZv8Tv4!~n`=W80yZ|x)BR6lCF4??Az2|!M} zfxM2yK)=T|tDAB-sV0ZlB1rb(jo%2<)G%V8r>gyELgVZK+*Ne9Mxw%pwP8TW>t=}( z5B3dctvf26RN=+yxNsrhqZm**pbEfObqtLA>bf-kNBb{Ck>f?O1+g}=xG!vFpSli{ zd5*S|jp%DHGq-h+eca?A@-Pw0I+u$@{hvF^Y7aY!w68jg^tZc+sof;<*t+4c#WlDTR({+4hi_N97<+W1TBrQMLw0u9=$O?a1=-vQP zVqTzZ_|hOjRY1u5jQ6^R!?}M`zeU?RaU*9pVi7bb7RGz&DaonS$b@XXvQrLTwLe!c zZuvQO@`wVxhUG>of3_>sVV-)ujC72Y)3$68wgBSo0eq)i|winspkayf@Yz-LkUkM79t^BrwXXorc{@XB4eXK5S5rUD+<175epLi=kD)|>?( zuBUxz^k*sTbm=)Jx9%L4{X7qUS$JNtZDT(1ReS;QbY>y@gV!ZucR&#vm~@#P<6g{q zTbB^eo|X_rT}p|vl2YQ({j0=Lc^P{rznm@Ia*fS8c%41`HN$?t`UX2N_$E7RMg^;H zT}iBtt77kWeQ$Za@feub8{2=_yk7MqeYGCmPmK4)Th`>&ecn$%eg^S2wZxD0Fb zgdEoBiFL3>&mM#|dM@8bf@coo>h$bauujj$z&bta2J7^!0M_XVt1tLEJ<)MAU#BPT z+Bgt(FC5qoCSu}JnV7x(%#k>F*oi$?>dY2wb76nTc4ZHwxUtLDxwES$co2J%J=vK) zUc}OI5;n@xn;;}Utc#8>G1^>8MAk|PJ1sxLIp2>ks_-ZJw!~b_o`4W!gGu;%?U(qr z#gDb;&)UXds&!@oWRfrzL1&GH>udm6W4;>P{{wjz8D*1w7xH;(+kBDz{B<^`MfOX; zm`eez0OPL$SI)kX^&5^8BBK*XP2D-da;E}uoOF}jT6B~2oo>K>^(m_IooLyO9{l^; z-OXmJ^qG(EG`N@kw8VF;nev>8Haba6eZ4JA2fXY7v>)(wNcr3Y!82b0#FaVa|3!5_ zb$bB&NB;cU=lk1UQ%h@m)|je>#`U+I1#_DRNGlFOyT!qLD@S0w>z^2>sCq;{M81_X z3d-bddqd5EEE0fBX2!uB#G=>LzcqG5M!x)@`x4)^cQ+?*MYy_r-jt8L&Eiq@?;Z~N zb23^8WOD(?=tdlj?+<$H-}2wGZ}eT|^FHJITyHqU(wYa_9r_W6%fSTi*YEIo>~L>*%((7f1WG1q*F{e~!gp+@BK;=5q;{ z*R{Cvtc>eM*?JkXeut5hNu~W-^;_{hjxatYKW$k{+|QeE@*lvx4uN}SH7(F`1PCN{BC;o2+X5ZJc8QC!+v`@^~27m%C7z$ z^GTPO#Hjl(yVuWed%I#)^Q*<@6Rz(zzfv%-^TGUn8xQfaT0s55IAU+F@(Jt%9iH;x))yDIs6Rj752~rv?gMiE;jCM0oqm%pn}KI={sck2 zK7lsf5h!dZ_zRZ;&199nV%daZd}D1fhc7Wh&R<~{7nd>y|HIyMfJKokJsu}4Vi-Xs zssl(m11l)3k&z&ai4`NBVI>G+S`ie(onv0};Hl4mGAQVYpo@wu9_V_2EO`+@qOKxI zK~^!K82;{Fcp``4-g)o+@B9CqufLwAir$^BuI{Sps+#B$#r?`s`IB8`(4N#7x9EYd zj#fpGibrMjgzi;A0?TUOXI0ffZrvXG7NkB58dCqrSA4oQs8>#%?~!efgO(3f(EO7G z?X%R7w%=q#yG$~M&u4(OmVZ7LGvQz0GqP5FyidXUOEwxe@O;xiSplAPEvQw|J_U7c z41-BqhJyl=ml=a+*8?zWuDew5N<9rr%u7@3=$L_#>oTC954CnDvb|wOPWg&!6AG|v zBX0{9s1{OBdlxCzjVU7BuJoagF6_%}{+XbEaxo;re2nOM7RJOT=YIG)O%uY~%oLyd z)Rb^mGsnrB<}LP73kRirR3H1S{)+b1+s%4^TYErj8~SeWjQc@356VUG%)d3$cLaFG z8Q(#j_Vaez*766OZ>nHVf-=y*Zm0b~i*)c?vOu{Fepj)FQucpf{r~ndINsk<{x_h% zZe43@FH-=TSbGBb-%~kfMu9mq72KFZy1GnDqTHu`o(~RJ6+u~6kR>gl+~uVTEV2w+ z;eSWq6?+%kvJTmxDe;{9f{az=SncQs0)kzEEjO$bL}*q~;ons&3LC1i!txqH=lqA1 zM#>|F-Q`;B&C5DP@}b9+Wl_DLakT=Q{zgr(qmD&wFH=_}W_O~(O1cZmrfRnEla3-g z0FI{x_9x!w*?c}x{R#eRnai#DYz7#kS)gnJWg8f?Up$q2g8JVX8_;S`_)>hpOY-yk zK->6$aPa%Df#_d?N?9_hxRL|heP`n)Wf0u3hLpa)G|_Guz8H2#_69inpU3~FLeD8f)ZcAv3&oD z908w-M=t zN^5Pk#61W0kgg=m#m7p_r6Cy>Vxy}+aAi^bInzT2NLBU>6mO>nac!4bauVmWrGC7@ zVuihxwBE{E9B49xYusZf=Zvb2boz4}acPw;cSiw-gQpGSc8ed*IdFD_)c(jwv2@oc z?#i{JId7KONzcqC#g?vPq=W42#g_&VED zkuze=Bx$v;t9a>;Jn540lf@0A+_+%_rf|&qPLXl-e{gswg8S`4D>7GSEjrQQ9AB~rwU5o&i`vFKv~o*j zqk|Ft^uhZO{CnaT1mB^FyicUI9S$IPVgstB3FQY-+rHo*2p=q%2!CbVVFWimg;sv? znL|ere8#pA1TR~C47E!a9!G7D*`Wx(+js`y9~c#e;0^;$Ab47zlL)@DOE`kRd5>yo zQ+)(#Z@7=LHE}I-Pb2);B(%dwJuaL<@aphL1V8x8Sp+xO8in9#0nrHV>T?dYC(SsI z+P7Rp2!A6d2H~^%UqJ9!-HQl5qVpvLuX&AX&a%2#)LvSKvO#g4<-{TUu&ZK(Zx$1e z;Q66f5d6n|zacnlLjr>DS&@j^yFIU>w$}7(2>-gH1mQc|UPtg}Cch*28l5BrH&;tW z@N=(F&5f=}L2c{O8wg*Xo{I1nBuWvyM^qYuA32_m;Lf`<5IjpcC8e3mvQXR217+gn zVv}Mv_X&J(|n{x-@r?}p2Sx?~ue5*8!|M9E&{EgFWx8e-` zP`9_vxAybss$~je z-!QcjMQ^44rg*=rtVL!Lg#YfXj%%Z#r%Z)s2bXnVDsx14tUcwT(zyrmM*r2hg8AGJU^51qk0 z;erBXq6v>b z7R*NsbuE~W80uOuA2HOmU_N5OsEH^av7qljWLFY&=wicMtQk&6T^hlh4IfGG**}We zy?Hb(2(V+8d6Bf+)G^FtM|*n65C_J(pCdlGw^Q5v0e>YPVMrTa^tSSUYrdNZ#*hcf zCNQ4C&Eu&D#?qzP2IzI=ov5w-&!A0gbnE`YKp)|toCf`!S)jE4T`BwEH~D{2CnldQ znFMWsf3W|3r`qw4*B{&@KXpO(N#s8{cI(G<{#rX=TYWhe(5ng1t&5M+mNCcK{j}op z$ymOVSx?z&onG=FmNqZ?l{P=BMn@(u*5waY#`-|sg0Vi3w_vOfZK0X+}x|u$6AO83IBmdRBHh%|wPONT!-TYEMo1K6zIeWz2GHjVP?|vhZ+(>Os+sz{ zqwixh!~X8Pn*XjdMqZYaz3jfH1Mj?vqb%9Mi5J{)tn8Grvn=|tvrMSsBHNqoBJ(RB zCtH4QJa1d(1lg256Uhz}rhZsYzkHzbxl6S z0T0F_fE#$E!Tp=fLpzR@Uov)<|Mu8feo)0lek|KX9#lR~zW&^J{(;O1^7(rv@>fMo8vPmm z{G`R|qf4pNh`-Wy)tYw#0Ud%si32o|f*Kkzn8?a~^!D*bneul>Y4u|vbZFW!de8df zcwS^EEttp9s=LDI=VMOLJC~lsEsVqQYpxNrhH4~!_E{vJoED9fr_a%gnDe;NHW4n| z9z%~7T%g1KFVY0>676dhM?dH$rt{y6=^OR&_$_Gyo+3`9*M?rjPanF5cR4D-w+CIv z*ZBU9FPfP|8`>q~6FDjP#o;$->C9BRsVJ2m-yw}2`6LZre?J{x7Mp=dYBMljDigm} znu$+7kVW|&UDl zkIAb$>dEtK6eQ#KM3Uk8RFW{IK@#ooOmf`%xn!^L3kjw5QnFm7QR30ih+7=(g6r+< zN;_@tM%x77w3%0T#&oJCt?sDBu!i(tUK#gf9%}VsN>sF&%m!^yM!61iE>D*UP0}MW z67-3LC<7uoq&IPVS07^Uy1oRpm>`zVHY7YI7!gxO8WWBK`Vm77ObFA?rp)AyW{mxF zGse2YoavWu!Sqb|fo{CipRNfXKo{>HNM~#wL?;AT($QY*mOP~`Iwh^Id@oKOQlWus_RQKpjyivk^>c0O8;7U`G*?v0<57AsCk9*?}{fMY6x%nw9O{~;Ol|B z&(BiB1jT@Fycc5fMGG-}FQ{QWdS&mVOZAD< zFsFOvThMA>=B?KJ)DQbQeHZGt^plV0aqCZeV*>sxXqm^_U@YwXFx#}{XgZ>vOP2MGHmQ@^8&`nIGz86#C`grVyGy#hfCsIp7uVRM}UBliV zkzi|su49XRf5+y`Oro^xk}*3@3KlW^26bg-DpgmMN{#A}Mh$wBhAqFJj?ItFP{h<` zDBP(`ET%LQb2yMCa8Jroi2SputdwlbBrr!27?q>g=O&}hN60X>X}O9SyK)r)RyV2O zEjO_|_dG1w8od@4FOr9l+x@JvKoKNoE`K{g?naph;FPXccUotvCe`H7?z+Gv{`=?Yjz776{!82IpL~z1xuX63 z6V@%U7GJv##Q~mhScKs|i#2bX!s8o@5aVq0rnnsu=r7gpF z5Wyibrh0rX6TRgolioj%+3S6a$Q_o?EO#m(F6!Q9rkE5G2VNBtg098Hs-j{>yP||} zk1r*LWS234C+-lv&fR5ZY?Kp?yYDf>Jnj?4OUfC2`v*kA#0uuEVI@;&Q$^@$R5Mq4 z)evtU)-WM29ujxbA2B}{)Dn`&I);DwF>zu?J!5}RL2UMWLd;wLlwqbc5M$;&V>Vhp zCyec0FkV_OiH?06nXwIxMAf@jjCtN`My0xma7uUs=Y!+7*-z1W&VTfIIjFVn@H3## z22fG~t%{my1?54>+Yh-U+uBDZWgqVsD$Vj#4fy|h(9e@aO8IHzJjY)ovs{zdDmKZI zk(Md!ik>$}cb!yGhxe)Eh(@WX{7xF#yD(jpay5f|AD7AAV3S3@>#i$G$kQc~pXjl@ zBK3(=xd!a9J9>+L{Iw5hn}OJZvgw0XrP4hAH){YmJ$y)wkUk{U~>HkE74YWYjVE+ z5Rvb&p`=68P|-MDThgS&Ry5!hhgAD*nCyq5;qvt05j^MLN6Mp?kK$RJ7|l)Tc&sd|6IZ?@i7Pw*&_(Wga-1wUeY||| zrU{>vpFY+VznFppnC344=MON%OgYz)L}y0`9}3CxtYcC4{i9 zOw9z`)IM2%dC4dQ2a{r;cd%;)LVGt)TddB4wPp7(j5H^_pQv8#)C<5WUiMp^QrM|R~s zTV%!C(6t-yvWGQqzD9T65rGY_w8)0HTSp+Cn=jyfQ)w$M-rZCDV~L%($F^Q#QJOt( zR6uX>SHTYASu^^Go&5TWU5E7(TTJXPw(dMYjP)HT)~+AO>ulyIt}J)ty{a87&d(ge zyL)3OuVSAQFZ=i~-o=f>dHeP_^AhK|h|jDa!P`D+quno{w;`2+>JI*$5{$6gc@BVPqM*Zi)UK9_tm(p3jM;d*_2Gx%t%OqXl4a+$GGP zE(B(qiE&jphZ^d;R z#oWymbGT;qX{~CE@5$Kf{t}-Y;Hi%3^!TM z)n~AeImmV_X~orNyw83pZM{$Mo3=hd;iFaRz}e{dZ{CgJ#`dizx~ATU91%IAYjj=C z_04cN<`ur7Z)SMtIq!U}MY;I~3y&6Pjf=Zv@Kj&NpxqH21D{r=1}o!C4JKL(LQf|P zLJ#?l3Z341w1J*5-O zmvxA4Bf5|9Q-?-_PY`cl{*|`W#oaxr9VK>DqNtZrE|;U9_;q@lJQOiV;x_g7(irpl zD=?-TBAXQ$Zoh)V{CtG>g^1YY8)klkL5+)};liyC4Mj67jTbJ>H5NIyGF|8uXDYJ1 zYqro~v$;s~OlPn?$f71;R~G=L5~5tn5=usPt+~I*3NG*3t>(OkHN07ET@xp;fhUV> zYPRSIU}UnOW=W+j$lTpiBrdT75u#qA#cB3{^64$|43^i1i0rxA5E0JRhKQbVwIMa_ zxY`iWy*PPoNKFY>8&Y$Ks|~67k*f_6rE|3*q95kCf*OPyO`6&p?L|0M2iuv_$Tqbg>TeSe5>`R zEwJG%zNzg#{|LUF*8DyAKKGV>N^isWVg+C&4`fh+7K!A)yc!hJuHwK?Z1S(Mi=7!gNtzMbu!%0uUP8hRU(}e(`+r9 z&8y>XpWk|${JhbRdU82VWxkXh)#bVo4+Lp)x$e72u4cX%ZtKgP)k4|DMt~Q`BdK(4(Rb^SJgB_ROotdLC?j2vr?9q!Z}uC=wHiW_X;99;pGep>)XJ+h^K zIMox(F14cqBYFY1bbD&*cfCRP5C?44fCH~qQ{Q}E9SaV8+yBe z32vjXqt8ddW!xIH&qvSi`=9c4(*s=IlpWR0KjOb$haQaPJp|2v0vg%9m;ViV(&Gc< z$I7E6=U6G%eln08?jw0r`Evd=C4-Y?EA-BKg^mD=*a-5sXG zz~p;vG6vUyp-DRACa4QGGI~t(bv{^-)t1?i(GITPug}c?35WBxv}eWyb%5@RIx@CX z4WPiI6T=^D2=xR;q@b%Ye8Mv!^)yU@?lV*J$z3z>xY(R5LNR$^ss))E)dga!2r^`? zCA>GOE0es~3Z5I#joCTY8pd|&&iLEffb0evW|FP|?7J;s20gL`n@{y5y-V%DqKIDP zz;t^s?z`Tkafkz4u%HiF>(>{0xc4K=C-#RuZ3d91`VNF`wFfab%p76$14kyaZZIs) z8Nx)|915zEofzuGFd*A8oS7Zw4ANG(kZU%K0HNbYlC$Qzf>piUNLRN}F#h={=IdVW zf3xYIP#!U0Wa6dG%aeWASArw&*q7+1_h+ZJ7MO26AC8B!8z8mF3 z19>_2bJwEJkoa-9Qm${YxC&A5NPiV?w}K~}r{evr;JHju@uC$x<$4y&i&OBF>nAKP zQNdHLv9P>UzvdV}qTnfQ2+KR6;7Na0@v;;=YKMw2+;$m9aeBpX=k8hOm;3=n$eKh~}d=1|V9AC`dy+ zjyj>gwNQMf^1*(lHR7?Y6CT_1!=_&;3*#TV9?m}<^E2N%E`o2kD^fB-O7m-0MMFPc}HW<{X&pcpm;q z=0HEoTw$8q|C@Mj7WP5*j7ubZ$nm6H8HBtJB2z)L# zVU8=vw|0Y!>nM=adNe$1{q-NF8XV7{WbZ$xH)NQZ-Y8C7tR3~E)2k!L99)+q{5iWZ!=`cIT_5H zXBUL=_(j%6K+l9rjB#`!SQJu3Ms&O*)IEBKocUOX{M}d&J9tSCi#*AvCdIU+W=Q09 zRrt%rI9xrqJxrL`fm}CQ-gowMvKQ>VDtBeJaDU9}LVQ-vPKN4r;6vhI63ILa$vz=~ z>tmFO^h<`Q9ML^Qzao0h_7X?0F#|L%s@&9YS5kTK9nUKehSwJ^V-$d@~I zR4+euIg7@2RU_HeqR|QaxSR#{ObKNsJplz+{v=oPH|hc%PGW}}}in-|u`i}~v3 zMTzZq+4y!VF=ia1@hdT$T*;kxO?kNO2G;85#-XM#67C~uaN@ft*ug#;dVaGPt{o5q ztY+?m1FU0Vm`xmPWh*}u8}zT*55Inx0EJf%z!ABLFz!MUw2C_j#?#5L_2v|~WJ@aT z3DW2^zjWGOc!>DQ<1mdo9HCeBJxV{*KStkwb&S4Tok487a-4X2?F4ZzFOw)ec9Px_ zd5So^`!rz|mPPCmogu^v&k{jC*>rE`bHp^q^Te4UIrJ5uTw3QwE@3jZ8J46om%ome zaF?BO41Ml#lM*{vUd1w{J)Gaj|9nXP@xx4~Y9EuS7S`;cE_Qks-U1NDZXmjY@K(E$ z^IyD@l%wSH;TdFjbq4wUo#W(pMJJg3d6~?fV<(wy@u!$?cb{gKiL;oQqBG3+g=ZNT zpKPYjm~%{5$Ma0b9yyGbaV}Y$B=46l)BB<$DeGrI-LmRL6?QbFPHP%bDbJ0lsQboL zaH$EkKHC&a&NRd5M00FscxP;#!~*mGwhK0QDS=IzZi$Wd?1~L?vch`Ub;C@|tubAG zcWOYRez}jE_sVV7FMYLNU;M zMmIG!mlnjy^_nQzLrc$QMS<++7u4BaM)XrLd17mcG*&3zmxX5!=4|aglQ(RwwD*%6 z__PN%VSMyG^4Wy@pnUx=jCH?X;oX1-Di|hpUZv@rCyn*S1tb3`(J)( z|KTzB5;RXKh|k6lsP2E*P)5JD?7RV_KUmVRewcV-|JOb<@5p4L3XmPrC4b9(8M8<&_V-|?vc7a@9H&S8|COcIY z2Bx^a{kuHgtpwi~R4Pp}yNoBzEW?>QWzq}oSMjr_uYPVmsed)!m$h&I$@vcjdLOPU zo=Bc+5UoeD-5JQ~N-)xs^N85yT|3jehqc$c5=J`|h11!{*8LnFL7VQ1B#v*S>6fdb zi12yQbl&Q{^f9j(qRx3AL0ZQWIW}>Goozf_^IJS!iX{-8$`S}zd4O1&n@E&gNFu!A z4$?t%GU2c}g_Z@sJAU!$kRgv>uu3j|nR1hhUm8;1j9==%;o_H=3C-gd#^W+=X;DTb zdR-xU*j**I+pG3HJpPT__fVK$PQN&Ji+*&7+xJiq%Ftu{?h*k@?$Ndr@6%H6Uub^c zUx}n)4+w$TL)zP*g3zn0Abjg9i6=K65ntZ=jVL<)n66EKLZt4gq8F^KCjJ!(X^&a* zeGkO^vE06gwwBz!hiZ)5_fX7m`ySG>HTU+!#6bVzAO-}cp~?SI1QtO@ODJg5U5-KQh{ z%!k8xjw6Thcw=KZ#<$jR7>~QlVSLLO4&zIrIE;U>mcw}OS#pd^$BpGM-piK5xW2AH zj`63J9L7s8a2P+lpTqdBEzK}qu3J1M7*q8B{mY)MKjM$L{8qPGF1M`TXl%Scq-m_C z&URsq_WJBa`V@=EQG_u=MHoH{jsEBjbW-;)qV<2bPD#5PUX)JVbx~?joG%?3SRlnx zFX299q4b{g^>+ijZ(T9bu&9I<%qdmsptOFZ+zzw4NNYA+`Bb|2Pup)Tgl*P-2Yi(M zR%INy-_*S4Jtu7DHj2fg&m?VgD`wX5LXY~5y|8tqIpP2 ze(3kze{7So-x1jOgqbrhTDWfYUXt>PksWg0$JkiM%GTJ#kv)1O$m;JVFk4<65cbJV zWSrOL2|KpBK>jiIf{-e_NFL137wRl2AqPj73N>6WGi^P~WUB>NnChNaWixcHk-Idm z%bY8(vu833rs+8dCLu%XN9~5+udSbC<&QHTocBiwTobZUSWw%wTnnIp`DCq8L?~e^%Fv z1g_uqx8$Iu7g~?T?^wCx531bpGnyWFUZDrR_x@Ns;ovyw=>kvbtsP%TqY}OF<;%xQ z*Gq)bty3mQ=PjLx|C_xdfvYL~ew9|G&(fljXDcl#DJn^+WC__B{~1?8jO8jzW67nY z80K0BHFaBT*+SMVSwo@1{Ikx*3|Znbh*9}}-@WhVsrTxY%$WJld%x57diC9R-#O3GRMDm(f5;a&B~{Ob z#IWPs*TE;azQazE>RnH94lbv;HEw6fZNsw2U#?}5_A2K{$@6nu;NA1wfW6sl@{??~ zHZ9={|-ThO7S9$v%w`%L6+K7XGXyMoW($GS7l-{*B_({8-( zjPv)g?u_&Ic{{e`kzmK(KF`~+IDa48u{eKUvT_!mzt8L(&FAkk%f0#heI~ROpTExx zR^#*cf%R71FTKXZk{asgwW}{t-G4}xcBF^meSLIs?eune^;i7S`sjz?23jlcXA6DW zGSFJdLU0a2HiA3^#R%RYz=hKPwMXmT9{txhR5RaDw)WR1c)w?AxIV>ITCM%8XeHMC z!}z`=d*3U!W~=iN8O;G~a|Fi_oSXyTlQ}~C`0)0mNbKXrx;eY)Q5?DMgKkcqV)^(n z^P3PqhU10!G2K;&AA?jOehk+O@nbOgK`NP4uoVOd@nc+13Ga8fo)X^ga6Kiw-+i|D zu|v1YwnW;Lzg_$o^CzZ_+Mg3H7V4L%SLCvqpS7zu7qH*X1u$x^VDoXO55)slCV?}h z8EWGEM63&89;wJ1Vy!LA8@SdM_v9R3LyPO$;}mN;=@c=|^)xl2MHaX0RTgpkRW>(u zbq>~L$g9jnqFwSOazB+z=tty{>xg{fdEjMow&xYLyZJS4#KUXs1wAct#Y-*R!<(FT zMTa%ZsLz>h<$HK@rHj8<9w^e0i~m?vD{XLp)F~ z9I&_s1^LD$md&{u%VnRABf$Qj$g-Gt){Noh3b8#rk?i!JB*Mf$nRA}_(b|>WPq}>m ze7d~{AIm0-n_cC8wECH*9{-GE+1%a^Z`o7V-jexd@3{1X@5uC$5^l}9QZDzmGIGy? z_uTH&fLtA@LVgveO3v)2#?4q*k6US@PIfTSAY1Ebl7>cFq|RF;LU9eA&%A4PSKD0)k+A|8$aWfiHtGyb*5x$MVZtE|GKY}hFAu)dpt<`>})Kkcb z)ccq>l;H<6!~>xSW`+Z}EL`Yw;gTx#1CZZTj%Tat)LA?m+qhr4Z%3qI+w=Q|`0(;x z2#;%MR(dMCq&09|pn|6IX?3>ghjlHxzN_-(FoGNi?_AzJQb1!+{eqSX!nfUn-ccvhtruH({ z7q}5d=h;EXRvy1SyCN@g&tuB<2H+~}8DF~IP=4;*_w2X0&15Zf&T<7;$sQ5>Ne#?q zPc-D~4qAY{{AE1#b0|Wj-?YyB8imy?tsOKi;)C z{_W7ngohIg80<#bWL0%#I==t88cJ*J|4y2@!u-S z9z5dr<@G>MLp-ntff@y%F(t&riVzG%JaHZOro|KPS;i8xuf!64_A87lK+V8>TC(#o z^xymhc3E2l?V_K;=3&nu4CbK9u;=iF-wSxJ)9>(#lzqGYJ zvGvmsOwZ1rw*T{cd=nk{YqYvE<4%YcE(k&q%tW+VL@l_CA71GYLXS1f@oF!d_$Oz-sLmJpk==p#Egpg9d;nX{7kKX| z;=5bYbC|V>J@PWbjN)w$N&3nwk`UFa(8d3woCQd#2f+=T@cJdFb~m-Mx!&DU$*FAeA%+dgz)asOxc2L=JxXk+lio^ zX9LCr%FW9mW9T}u6>1$1KHR7L+&KKHnKKM?>Xx-dF@D$gV2er51W%D;a ziw(bWvIaN3z9#49tHlj{tVIsB)8SmRbx79+x>){l?616!hb+CIPnt}FLCb1Fm3^W;R}S^($5*2#%mB{0V{d=8$_aT{+x&q z&Y!a}A&!4$&mmEl#yF_l_el_{O6`Mcs=WX0rCrtQR#BXK1){@cM2}zVkRFO`n=k#W z0NK}j7{)=x^8y0<*DSx+(dGmGm7&9Hg#S(v0QQIgY%fg56sdn}X}wB51=c0uQk~hJ zc1tbfopH%MbAs;+k9((ijuU#PVgHuGy=v4g7kb7!S8>mxM{abd-7>n+UQr&jS!`Fj z)mTsH8tFx=ckc#GgS_bnZG2#9^=IJV_sis-fup|ZG!WCQy!P}d;mlia^t-y6LjRXQ zQQ>vtH_5jcwuFB)7=cfXr-cn0raL&hp#>ihfl(Peh_~ zt;l2fb<;pTjuo99tmyBN&40U!@TnS!^!P{sn?wpdg~Zt8m$GMzxLcKQbr2o{LkG_( zKR>42b}ZC~hw|}eF8#eKznCq;O@9PK5uO6kh}#I}v>P5@9=EjtiT+bUQ`o&}X9Ipb zQ%Qejv#0&Fx^o48yR1AC<&Tq~4@uADsVaT45u?w^NV#>dtd4vc;d}BzSO~`{i42a#04Y{lBjo6DNM&v5clo)xVDYrA{PxAwONm*stadTiFWd3v9daj1)|Zn zh*opai0e?u^P8~oiMd?qZ+Ug8-{4+~%AVsbuX&sHbb=_4r93JpWFd<}0Y`;RY9})k z?Pr+Bmm_@bN05PVcLt3Zy^4HM(1c8)NBAUH>67xEmnYWID9`DZ`l2{XA(#HI-XBFe z*pK{hRvkZFYbRgCEt8is{q^P3sH(k^MR;!-g;cyK0PUj$*&WclU)glO>?(WE3w@T0#_0bl@nF#x^Jwcfl=k^BPt)-&M9m_%aE+>P+|j7l;L9E!{( zSFGmiQjqTh1sR5O<>k}>!gVL8^yh`thC2_bHF=M~nkG-codG@P za~22O)1QOkU%de4t9}Qa-Cj~|b6S;e#Al+K_=xQ+$&r1tej>QdhtP%aN^ zc*3t5L5XRereqFJRWTLaMS#^uFnSSy-=WbG^G>qVxA7qL;~bu!kJM=nkGN*5vTYUZ zJ6b0NIf(1)O8p6P1J<(Z3Y%hYB+B6|S0aBsRiy{~fbh2;K?cI*nMHz+{RCQ9MF?I= z>yLp6M(6pyp#H_#VBm?Izj_}R?Of^+*BXye8ds*u$|pg;QZ8_W?Oncs4|@EeAs^4x z`JwM3yxm7oKN_%&qX9IJu3S6RDY|kET36|NamC>=X}9h>i1)9`-@ml>i??tMu~w>B zA61lz9_Sk0=retzKlEq(b<2m^^Y|g#pV4fzFkh^xD)wjWkLC|W*BLHzofHefe;_;m z=2ybJ;1M6sAC2aXL-WU@5&u6GIO@8*&lex!_YuEGD4I7D&Hqk1Kk|N1w7mHx9fWz} z9wE+;K=T%%`7zS@Yfsu2$(vv3BmeVPqIo}}`Rk&EUI}Z}=f!vysT(_l+%U#|_S_#X z_7tzj_fnA2{R*8wzNd=&Rx-NgR&?zhB5quBmMfwUaFYN14xzcn&^3-n|MTng|C#mq zvk^YkVgPIuQ@I9nix{CEIqkMFp3=-npv|Hf>f!oCS~n&e7>~+_)8G67h84bpLkmiP z+u2g+dY}xLZGI0;*W#eD3M`$eN|{VmqnnPZN0kJq)9*YrsM`*jwDVF;DidnMUE8&( zBurXim2XBpKHiLew9A~jkk}kHn<1fg&Tj$V4{ix^CbWWg zoLhq(z1qN&1{Q#}wxoY4vjibJR`l`PR$$O0YdZO;4MkqIr5DDxqXz7;qsN8YQ%)-# zVC1;=lwqhN9P8JCdV}=+9+uA3b)@fGYjy&~rY=zTfeX0y&J{jA;|4Nrbf$IE+`&&7 zUFau2cz}7aUFnNcJgL}7FFLJXH)?K>H@(8%hZ^bQ3s3*<3+8vyO1GV=##oN3N9*)gXSBUE=qC=EjQ3Ja`Xbbp9NVrN_mP}EZC8Tt$m`k^oQqZzH6iR1FC}c_C*sob}6NbeDEi74E4{g6z2Y-(1j_VqfGGLS|gFqs?=KU+L@ox6Pf(X@Y~SW z!j$2!sP&;pvjQ>QNprb_0+Wh4A}++Yb<;}Ng((?_xAUw^2}PHblsf#vTz$<`*VJ%5 zoV;>3RA|iMF_fixF;T~2Jo?(ZnD)dnRBFsF4%591?C*U?qHO)!3kU9_%xYa6EigY) z!PK~U75xXjuXPYN$bE43yX+uO%0(gUeFh?sa}m!buli74>g(NcnZoje@3Y-yUs9r@ z#jiqiOA1T^^sj~%l6-GQlCDesNHkW=!rWTTmjpgmKLqj&@fZocE$%o*h1a}HDI{Uy zRH3-umsyJ-z0&Sv+7hW00nm}3(4(jkW^>?=Y-@Gpq%`tw&rX(0yF)c)J`t0 zKK!76y@zzh!R3<{&u3HcZng|GFpwu;F{q#-NF=yon7-P!4%a4@I!F7f3XS6)%PJI3^yhNafksloBjPZ2EN(f-okqkNy< z|45%!S>b!Hp#2sr1heJIooXei&+;-kEe7qmap?-&7-O23?X{FOEmBGy zZ9$+AFMAJT+nSK3V>5!3f$DroFIP@Pzd>n2og}XDziZ)v2~b^v^U;jf-|fOnGs`rh z0nn}YhH&#ITHd_AAwh^@szcP&Igbnl93hT^`UOb>`t~N$ z8iwux^;Mfwq*Z3+u>&PLx>cgR^a&zT${vV`&4Dh1_w}>w?-SbBokd%{*Ed*$DmIHm z;HTNb-cTj0{M7ZR44oip8-_hE%oSo65)0!zG_YZ-@H%qEg zqS3Um%&A1`g7+sgS6Fr?5;Ip1CULDdAHK!zdBtvN&<&$hs<}&$XAi-5bwG*iH$L>c z#%c3skf;J0Z7;El<#H$UyR0+9FHLeGxP3l6Dkq~29AtB!&oY#ZV(IZq`xu)e;(WA; zH*w%83h?MO1w*r%?Ovy3jV&e3Re=T#=5;gjyI5j;Y5&@=J=imx)7|e>P3tLC8&izc zzPHE5cVz2gO*ix&*PL0~r(I2uyUOvKyL~HyzM&yk@wv_Ay~0VN&9MeZ13F;Qx0G{a z3bdmt{v6Z!FNSl&>f5W4?Y9J++bAScO)mA;Z^&||e5!KHC0?JaqtmT?f7H`Xmw+>^ zf~dNE&3#zmwZFUAnKL1+Y2o^Xm$`>hoRVD$!?H==L$e=EZ7*kN%T-I4DwHB_OXIbs zpSeXB_4TWq{PIcR6Jo%q14l;4u7IzD&OK^s6zS|HZ(jC5o23;4rp%Vun3vBeXTD>l zTVW3r?#40Q#%&xjU|U3eJ{~E-|Me9n&63-i?V{O&??Dl$h$&BcF|Vzu^P5Yv7y+%- zVaw-S7@AT9`f)uu@^p~J$#7MrH5*eC(B6EPxW(=-@cYRnV<63)GjwuC`J7As&&v^W z)rYma36w`NRgL14S-{V1=ZS#)n@RjRTf)0J{U-WM11Hb%tv|@vL?H+8$Ui*w(;nCJ z=KQfV&!~s}yPXd&p;K{N69tZW;={$P-QpjYK2Mhqeq!?{ub`O4^+NnPvOD+tU^-nh zV)t)-KR^i@B>Q_%COU31{+C!|NsBo$yr~%w#KzhNMoI9MSlSO~R|P<1t6g+nKmroV z&*9_W)%D^8x#b(w)?Z04+uMtbq2W@8^)+Six?A+iS0aCY1==5!1U3`Nm`4LobjlUH zZs*&BI;Yl;!HZ^r4JV~8rNYFM=LEtvpD1oE7CPq@ntQgH^7#d&Yuqzl&g7$g%|cGA zf#fm77k>{qGr;5ZS!|8E%X_CY*EQu6#+4SesR8per_ShHNigGdn4}0ikfZ|U@LIeC|(a^g|pu@FvLHk`6L&8bfn0R&z;kB$-V~8aK#=zol?yGqp8dsH;mCpv| z^fRNNkJ<4S{@Y*t@=}!FGnOm#oyBM6P58adx8Rbd+p~0cnuu1-?-Sc#s%GeXvKctid6o9B}7w)f*RpoumOEn z*e8GIyrbV6cD$y`4)k9x&bpumojIbA0voxTFkIRod-Lg0wnSb@p$0qa3>_h1&(9|vXHFy?Fzd3F^ChLGh!Rl>qU+V7dXV_cr)WgS@5!3Ui= zf7suj%je{wotj$G2zR&SQJ)#QZ+=iUo|Ft6<<>fwqIEuJUb;aBzN|(?DKl-X5-}Nk z?(xvShKZ$q((|N7rEL|VZ!!BHzJnMOl#6ZGuhK7W-!o5INmXF)o!Q-Az6dOoid}Yv ziR7I{oC7b$mG|$Z?jKvb6vBc%ZyE1_53N~eRG99JBwIMI|CJ=-m|ar<%St%>a4b~+ zvYUuD{CsjI`8Vo1L7ud&j85Du$CvCs z2I>M!G($q}lx7x7jHyGfQ`Ex@mKYzJe881Ee(ZmF?=$7-e6nboVc_#~f0;|Sz#^3UAd{Zs*n9HK`*5TSxWK{T zKHk;(^s&j~d$ETif;^jEfZ4gj2yxQZor8JgEkT$xG575lh)&~{uf=YVbKvzxR$vpi> zMt<_?=QOiPv|-n~PiH}AS7#p0RQ>1}a}2I?&`Kx@rylC4?Mx=5#?2vPiGfMF-e5Xg z!HDZ@^zzM+8?LNC&lh~du#OmmQK?DKT(`M)hR~|J7qY|ZGG&ri?@MQN1VJ zKN1|T)40w6oj!@tX*%HL$P83asTPYGf1*s_?@uf5KTk^uckIqSbhQqD>^wXccSjcQ z;X+fT`n|BvDEb{uip-D4=LmCG%kwK&&GF|FRTQe$F7Q&yEXYhL_^16t5BreFE(WfZ zs&gq!m>?z1X+xeaZ%nn@agukobIq8)Lgop)sW;Dyc5V!x<{r&%qI_4-%wnh48r>jQ z&NrA-@X{i`ux6+r@H$;{@ZFZqp_<1oe5MSKB4s94@s#k_Fe$kM*{8R@>zNTtcZoa; zCc42c!%fWT@a7*{rWAVETZ$jGBdj_88sI_q)bYp-ArVB)K1rx`KlXcnl$3+)0@M#J zorxMl0;L9Se(|~vGBw=h^mgZ}VkLlixEHLObV+co_yC?TDlmN8`n~KI*mx5E=zeL8%(Ru# za1ScOx%`-4AbI|FAY=Unq}PoqK&)9<9vN9|G3Bw(2&ck@+BdM1MPsB zqDs({gTdE;lQ2vYKF|u%&ZL|u=0N*Js?3=Zj#)T2uT4k+5RY#@rN_9nrMi@c`Z(hh=KXfR8jx*Qf0=I&S(~HJ)5-J%#&7!a&g8lnnUOS}va?&>vEOICRgIb?!xrGj{F{PeKg}ff z@N4_te4}|EkPufl#NrPfDe!9milF3BddNJ4;D1I zUH*rSgx_vy4Te~v$l)UB*EoCC{#%}pYOy3-9F-q_UeY9g*x-|7=FuE)k`V|?f98{w z+5}^@4J2kG*p6trPgK@VQ-ndz5ZYJ*jr^GvfgCl$ke=2fBkm>#!*p0HQZgQWt`{g)5iQXS8??}?=0?i^6R_X+qTXjq(?ex+%$i*k2 z5P{PijikMU-|8siJpx(Qb5-JBVw)q>$GTpZtWI$Uuq-Y_7O#30C~y`uiWaYS2#WH^?<gz|c@B##>S(tRoyB!4`%a8Yb)?M3M`S^T({{`v9k?83}6yxJh%dn^W zrjq*s>+mPFvWEKi!kL~=L*=n}H67cp1*X_z>1tRaZ>-wc8=9f~6D}L}4LyRNi-pw` z55?0N=l1e`?bX?L&G*{rTD6OV2-fBY93Sphc8ilXX1PuH%~g0^%bsS(u#_e z>Bek4r2U$5f_(+gC^>bZWc|<`YPbEQ@3MHUekGOV(F0d=IO@?N_A?X<{3E4ia9IudYe6lp#Q;GA1&OZY9b~7&(cqgQlDx$VyhgKx~5wc?AOSPALkLG1L zTTb)5EWGc8M7R2Yw=6R-oUKYMiU3EM%+8Otv-mKYEY^fibWQW=>Kz+}>maB-e7k40 zJM!fF+c&*vs+6`jr(*rwo@zE5j&ZYN1X_Gjhd&W?Oxgl-m~V|r%Ze3XM0UK>s!TN{ z6K)f%c9E>u+sEtQJ=fI6A?XkmRT_eZ;M_%S{-iqdj(39s$+-kP)ygb({EbTHR#L-N z$x}UG7DN56g`=8$^cMyIm1Q#Z%vJcV12p=OljJyNbU5d*R=qiR^r+ z0rPgBy82@a!6UBJ;mY-D@CftQ^Gt~kXIq^;{^u{}v+9+#-v`OJwR{ThSp0fj0tXFm z2j$$?62%>8!=*!d1c>VU3UKPJIg@Dl2QOUygyl+zIA`KW*sN)}9J^`5*MrT?BDmij zNI+f7E}KP6^^Q8pDR0;2BthIADA+&a^AW{<>FLkgXe+ z8%58Pr?i!wi1n9xtJxI(QC(x<5$zs0_$l@+wh#fwd|NMU{ z?A!A5^q?ga~1XVV5-<;5J^{R?Zs)ORsNq_VDQ=E2+IL*EqQ`|P5 z7`QkNI(ehFom`d%X}tCAxkXOrgd};+8k}5C2_;XzstLc^U^&`~WffRThmDP5SCtF6 zu13J?Y>D3xAb7SEtJG+*C{3}n1d{&ptFaKTW9a*BJrkReUw_9L#;2WtG zLvc{oktv-!8HH32ryVHv-U|gQzBvT$&TSlVl8|C~)1{F(CO8u=6{>?o=ku`gIabt_vi zsChPJE5LPOJEOHzy({N&MB^HaoJ3?Dgxdrq#~x^J@gV4zjz_COB}>~o%hjN-4}<8r zFlaZRFpR{VKJOY@5Y%ynFZh7Er(7SqE;>aX7Ry|W@E3)mdGVDLmMyy;fYJ8GWD2F2 z8*bXBmaqQ}kgVPWKkc}k)KkFODNR%*aV=?~*c=$aT|NqRvtSDMn!Nfr9(i@`nXslg z)z#@`3uZ?Gd%Pg`SgT7H1LF%kUy?eI4Iu{wBR-sF5twGpf~lT}9z6(Zkt7qB279QH zDL@HpO%eC|F|v)!@~N5j0T2Sr@PBoH5s!J{!bZD?BSS z{z7pUIE%M{vxF(HK|)7thSPX4OD zejAR15#8o&xg!(q5z_xbPr@ba;A3THjtfE8@fW zN8stIAcG9;jFV^wMcdx0p47(}_BPHH*7_x0j8$lxsf_S5tCz|A_^YMC(=c4h-}^`S zt6aIVKEZ^a!bgEoe7H#f5KK{&q7NgmBE;7c(+$Xm$<7Oxfh|swST9;MBvOP~iq(^rhftVe89?TrVCQ(R^~D9KXe)aU1V_G z$Scyqjwi&%o25NSwVt4c@SSbGun6xg6QE|pVmDC5i5rzisq2M6C_8!=t-#1PtkU1!}BkI36ssU@y8 zf*lj?{!Y-p^RuV1$6dzc#>n}h8|*tu>t)6sgZ&hX)>HR(Q6lDuFi)AfjRNStRR7c+ zO|nGDk7a|^h7l36E+ZL(m4~t0#>_xaU!e69r;4PWKoT$zyd4bC$D|J~5583ThnG$M z&m}kB@HOcUa3<%VFtMKj+Y-%Ep}NA-C3Hi0@Qm$q#mI;7B*09tLp@zH_A0OCq2UYU za{g`7Z`)qbYbyLxpyd^72UmJqB10L4O`CA|yeJdRQyW>cv%`PhZQqsZL1wohHEyv- z%b2H}D@XX=fCWk~;^Y?0tti@YDXE1vbnu((-xB9ZA3Ydc|EhbDPdp~#aAP(|v}^gO z?c&R(`o3~HWS_b!Xb5^K@GMX}_&Ky;2WLw-wr84djS}c6mH!t(l}G;w}JO8u#JJH83K0UIzQ$B;`5D4#67$9Mdo+NK}RS828@^rYTO3T$5N| zR`66C_X>#{g${5km}_C8gMJRrNX|%O9k7}oOl^rj!^i+D>MZ|tBoeIK#%qb&^@9Y8 zbC>xcy9Gc6xX16qY}W=(ge*0Z(qVnXk-ZP;m5rk(zW|$ki`@VAymt5~2F|2o-PrZl zn=1~*qyNLGSHa6qLN!ysa_ge6W!DDzg6 zsMK6{=75CmQIyf6+W*3eS^xk(_AWNAJ|6!q7We-x7WH`6QU)GNX@IL?-^N3sk literal 0 HcmV?d00001 diff --git a/tzdata/update.sh b/tzdata/update.sh new file mode 100755 index 0000000000..ffa1e19ede --- /dev/null +++ b/tzdata/update.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# Change version.txt before run this script. + +THIS_DIR=`readlink -f $0` +THIS_DIR=`dirname $THIS_DIR` + +TMP_DIR=`mktemp -d` +VERSION=`cat $THIS_DIR/version.txt` +BASE_URL=https://github.com/unicode-org/icu-data/raw/master/tzdata/icunew/$VERSION/44 + +echo Downloading and updating little-endian files... +mkdir $TMP_DIR/le +cd $TMP_DIR/le +curl -OLs $BASE_URL/le/metaZones.res +curl -OLs $BASE_URL/le/timezoneTypes.res +curl -OLs $BASE_URL/le/windowsZones.res +curl -OLs $BASE_URL/le/zoneinfo64.res +rm $THIS_DIR/le.zip +zip $THIS_DIR/le.zip *.res + +echo Downloading and updating big-endian files... +mkdir $TMP_DIR/be +cd $TMP_DIR/be +curl -OLs $BASE_URL/be/metaZones.res +curl -OLs $BASE_URL/be/timezoneTypes.res +curl -OLs $BASE_URL/be/windowsZones.res +curl -OLs $BASE_URL/be/zoneinfo64.res +rm $THIS_DIR/be.zip +zip $THIS_DIR/be.zip *.res + +rm -r $TMP_DIR diff --git a/tzdata/version.txt b/tzdata/version.txt new file mode 100644 index 0000000000..db18f8311d --- /dev/null +++ b/tzdata/version.txt @@ -0,0 +1 @@ +2019c From 5e525588bfe060af1a65d0961764dcb0c7dc87d0 Mon Sep 17 00:00:00 2001 From: Dimitry Sibiryakov Date: Tue, 14 Jan 2020 17:49:43 +0100 Subject: [PATCH 12/39] Use static_assert to check ODS layout (#234) --- builds/posix/Makefile.in | 22 +---- src/jrd/ods.h | 206 ++++++++++++++++++++++++++++++++++++--- src/misc/ods.awk | 112 --------------------- src/misc/ods.txt | 185 ----------------------------------- 4 files changed, 192 insertions(+), 333 deletions(-) delete mode 100644 src/misc/ods.awk delete mode 100644 src/misc/ods.txt diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index c16801ea95..1d97d66a6b 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -226,7 +226,7 @@ $(TOMCRYPT_LIB): $(TOM_Objs) # main build target for both debug and release builds # -.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest preliminaryCheck +.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest master_process: ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h @@ -234,7 +234,6 @@ master_process: $(MAKE) export_lists $(MAKE) external $(MAKE) updateCloopInterfaces - $(MAKE) preliminaryCheck $(MAKE) boot $(MAKE) yvalve ifeq ($(IsDeveloper), Y) @@ -306,25 +305,6 @@ cross2: $(MAKE) cross_rest -#___________________________________________________________________________ -# preliminary checks - make sure platform is OK to build FB -# - -STD_SIZES:=$(SRC_ROOT)/misc/ods.txt -RUN_SIZES:=$(GEN_ROOT)/ods.txt -ODS_H:=$(SRC_ROOT)/jrd/ods.h -ODS_AWK:=$(SRC_ROOT)/misc/ods.awk -ODS_TEST_CPP:=$(GEN_ROOT)/odstest.cpp -ODS_TEST:=$(GEN_ROOT)/odstest$(EXEC_EXT) - -preliminaryCheck: $(STD_SIZES) $(RUN_SIZES) - diff -u $^ - -$(RUN_SIZES): $(ODS_H) $(ODS_AWK) - awk -f $(ODS_AWK) <$(ODS_H) >$(ODS_TEST_CPP) - $(CXX) -o $(ODS_TEST) $(WCXXFLAGS) $(ODS_TEST_CPP) - $(ODS_TEST) >$(RUN_SIZES) - #___________________________________________________________________________ # static library - various common code, used in different FB projects # diff --git a/src/jrd/ods.h b/src/jrd/ods.h index 9b3d432906..73fd2ae28b 100644 --- a/src/jrd/ods.h +++ b/src/jrd/ods.h @@ -33,10 +33,8 @@ #ifndef JRD_ODS_H #define JRD_ODS_H -#ifndef ODS_TESTING #include "../jrd/RecordNumber.h" #include "../common/classes/fb_string.h" -#endif //ODS_TESTING // This macro enables the ability of the engine to connect to databases // from ODS 8 up to the latest. If this macro is undefined, the engine @@ -234,6 +232,14 @@ struct pag ULONG pag_pageno; // for validation }; +static_assert(sizeof(struct pag) == 16, "struct pag size mismatch"); +static_assert(offsetof(struct pag, pag_type) == 0, "pag_type offset mismatch"); +static_assert(offsetof(struct pag, pag_flags) == 1, "pag_flags offset mismatch"); +static_assert(offsetof(struct pag, pag_reserved) == 2, "pag_reserved offset mismatch"); +static_assert(offsetof(struct pag, pag_generation) == 4, "pag_generation offset mismatch"); +static_assert(offsetof(struct pag, pag_scn) == 8, "pag_scn offset mismatch"); +static_assert(offsetof(struct pag, pag_pageno) == 12, "pag_pageno offset mismatch"); + typedef pag* PAG; @@ -249,6 +255,14 @@ struct blob_page ULONG blp_page[1]; // Page number if level 1 }; +static_assert(sizeof(struct blob_page) == 32, "struct blob_page size mismatch"); +static_assert(offsetof(struct blob_page, blp_header) == 0, "blp_header offset mismatch"); +static_assert(offsetof(struct blob_page, blp_lead_page) == 16, "blp_lead_page offset mismatch"); +static_assert(offsetof(struct blob_page, blp_sequence) == 20, "blp_sequence offset mismatch"); +static_assert(offsetof(struct blob_page, blp_length) == 24, "blp_length offset mismatch"); +static_assert(offsetof(struct blob_page, blp_pad) == 26, "blp_pag offset mismatch"); +static_assert(offsetof(struct blob_page, blp_page) == 28, "blp_page offset mismatch"); + #define BLP_SIZE static_cast(offsetof(Ods::blob_page, blp_page[0])) // pag_flags @@ -272,6 +286,20 @@ struct btree_page UCHAR btr_nodes[1]; }; +static_assert(sizeof(struct btree_page) == 40, "struct btree_page size mismatch"); +static_assert(offsetof(struct btree_page, btr_header) == 0, "btr_header offset mismatch"); +static_assert(offsetof(struct btree_page, btr_sibling) == 16, "btr_sibling offset mismatch"); +static_assert(offsetof(struct btree_page, btr_left_sibling) == 20, "btr_left_sibling offset mismatch"); +static_assert(offsetof(struct btree_page, btr_prefix_total) == 24, "btr_prefix_total offset mismatch"); +static_assert(offsetof(struct btree_page, btr_relation) == 28, "btr_relation offset mismatch"); +static_assert(offsetof(struct btree_page, btr_length) == 30, "btr_length offset mismatch"); +static_assert(offsetof(struct btree_page, btr_id) == 32, "btr_id offset mismatch"); +static_assert(offsetof(struct btree_page, btr_level) == 33, "btr_level offset mismatch"); +static_assert(offsetof(struct btree_page, btr_jump_interval) == 34, "btr_jump_interval offset mismatch"); +static_assert(offsetof(struct btree_page, btr_jump_size) == 36, "btr_jump_size offset mismatch"); +static_assert(offsetof(struct btree_page, btr_jump_count) == 38, "btr_jump_count offset mismatch"); +static_assert(offsetof(struct btree_page, btr_nodes) == 39, "btr_nodes offset mismatch"); + // NS 2014-07-17: You can define this thing as "const FB_SIZE_t ...", and it works // for standards-conforming compilers (recent GCC and MSVC will do) // But older versions might have a problem, so I leave #define in place for now @@ -298,6 +326,17 @@ struct data_page } dpg_rpt[1]; }; +static_assert(sizeof(struct data_page) == 28, "struct data_page size mismatch"); +static_assert(offsetof(struct data_page, dpg_header) == 0, "dpg_header offset mismatch"); +static_assert(offsetof(struct data_page, dpg_sequence) == 16, "gpg_sequence offset mismatch"); +static_assert(offsetof(struct data_page, dpg_relation) == 20, "dpg_relation offset mismatch"); +static_assert(offsetof(struct data_page, dpg_count) == 22, "dpg_count offset mismatch"); +static_assert(offsetof(struct data_page, dpg_rpt) == 24, "dpg_rpt offset mismatch"); + +static_assert(sizeof(struct data_page::dpg_repeat) == 4, "struct dpg_repeat size mismatch"); +static_assert(offsetof(struct data_page::dpg_repeat, dpg_offset) == 0, "dpg_offset offset mismatch"); +static_assert(offsetof(struct data_page::dpg_repeat, dpg_length) == 2, "dpg_length offset mismatch"); + #define DPG_SIZE (sizeof (Ods::data_page) - sizeof (Ods::data_page::dpg_repeat)) // pag_flags @@ -318,9 +357,8 @@ struct index_root_page USHORT irt_count; // Number of indices struct irt_repeat { -#ifndef ODS_TESTING private: -#endif //ODS_TESTING + friend struct index_root_page; // to allow offset check for private members ULONG irt_root; // page number of index root if irt_in_progress is NOT set, or // highest 32 bit of transaction if irt_in_progress is set ULONG irt_transaction; // transaction in progress (lowest 32 bits) @@ -329,7 +367,6 @@ struct index_root_page UCHAR irt_keys; // number of keys in index UCHAR irt_flags; -#ifndef ODS_TESTING ULONG getRoot() const; void setRoot(ULONG root_page); @@ -337,10 +374,23 @@ struct index_root_page void setTransaction(TraNumber traNumber); bool isUsed() const; -#endif //ODS_TESTING + } irt_rpt[1]; + + static_assert(sizeof(struct irt_repeat) == 12, "struct irt_repeat size mismatch"); + static_assert(offsetof(struct irt_repeat, irt_root) == 0, "irt_root offset mismatch"); + static_assert(offsetof(struct irt_repeat, irt_transaction) == 4, "irt_transaction offset mismatch"); + static_assert(offsetof(struct irt_repeat, irt_desc) == 8, "irt_desc offset mismatch"); + static_assert(offsetof(struct irt_repeat, irt_keys) == 10, "irt_keys offset mismatch"); + static_assert(offsetof(struct irt_repeat, irt_flags) == 11, "irt_flags offset mismatch"); }; +static_assert(sizeof(struct index_root_page) == 32, "struct index_root_page size mismatch"); +static_assert(offsetof(struct index_root_page, irt_header) == 0, "irt_header offset mismatch"); +static_assert(offsetof(struct index_root_page, irt_relation) == 16, "irt_relation offset mismatch"); +static_assert(offsetof(struct index_root_page, irt_count) == 18, "irt_count offset mismatch"); +static_assert(offsetof(struct index_root_page, irt_rpt) == 20, "irt_rpt offset mismatch"); + // key descriptor struct irtd @@ -350,6 +400,11 @@ struct irtd float irtd_selectivity; }; +static_assert(sizeof(struct irtd) == 8, "struct irtd size mismatch"); +static_assert(offsetof(struct irtd, irtd_field) == 0, "irtd_field offset mismatch"); +static_assert(offsetof(struct irtd, irtd_itype) == 2, "irtd_itype offset mismatch"); +static_assert(offsetof(struct irtd, irtd_selectivity) == 4, "irtd_selectivity offset mismatch"); + // irt_flags, must match the idx_flags (see btr.h) const USHORT irt_unique = 1; const USHORT irt_descending = 2; @@ -358,7 +413,6 @@ const USHORT irt_foreign = 8; const USHORT irt_primary = 16; const USHORT irt_expression = 32; -#ifndef ODS_TESTING inline ULONG index_root_page::irt_repeat::getRoot() const { return (irt_flags & irt_in_progress) ? 0 : irt_root; @@ -386,7 +440,6 @@ inline bool index_root_page::irt_repeat::isUsed() const { return (irt_flags & irt_in_progress) || (irt_root != 0); } -#endif //ODS_TESTING const int STUFF_COUNT = 4; @@ -427,6 +480,35 @@ struct header_page UCHAR hdr_data[1]; // Misc data }; +static_assert(sizeof(struct header_page) == 132, "struct header_page size mismatch"); +static_assert(offsetof(struct header_page, hdr_header) == 0, "hdr_header offset mismatch"); +static_assert(offsetof(struct header_page, hdr_page_size) == 16, "hdr_page_size offset mismatch"); +static_assert(offsetof(struct header_page, hdr_ods_version) == 18, "hdr_ods_version offset mismatch"); +static_assert(offsetof(struct header_page, hdr_PAGES) == 20, "hdr_PAGES offset mismatch"); +static_assert(offsetof(struct header_page, hdr_next_page) == 24, "hdr_next_page offset mismatch"); +static_assert(offsetof(struct header_page, hdr_oldest_transaction) == 28, "hdr_oldest_transaction offset mismatch"); +static_assert(offsetof(struct header_page, hdr_oldest_active) == 32, "hdr_oldest_active offset mismatch"); +static_assert(offsetof(struct header_page, hdr_next_transaction) == 36, "hdr_next_transaction offset mismatch"); +static_assert(offsetof(struct header_page, hdr_sequence) == 40, "hdr_sequence offset mismatch"); +static_assert(offsetof(struct header_page, hdr_flags) == 42, "hdr_flags offset mismatch"); +static_assert(offsetof(struct header_page, hdr_creation_date) == 44, "hdr_creation_date offset mismatch"); +static_assert(offsetof(struct header_page, hdr_attachment_id) == 52, "hdr_attachment_id offset mismatch"); +static_assert(offsetof(struct header_page, hdr_shadow_count) == 56, "hdr_shadow_count offset mismatch"); +static_assert(offsetof(struct header_page, hdr_cpu) == 60, "hdr_cpu offset mismatch"); +static_assert(offsetof(struct header_page, hdr_os) == 61, "hdr_os offset mismatch"); +static_assert(offsetof(struct header_page, hdr_cc) == 62, "hdr_cc offset mismatch"); +static_assert(offsetof(struct header_page, hdr_compatibility_flags) == 63, "hdr_compatibility_flags offset mismatch"); +static_assert(offsetof(struct header_page, hdr_ods_minor) == 64, "hdr_ods_minor offset mismatch"); +static_assert(offsetof(struct header_page, hdr_end) == 66, "hdr_end offset mismatch"); +static_assert(offsetof(struct header_page, hdr_page_buffers) == 68, "hdr_page_buffers offset mismatch"); +static_assert(offsetof(struct header_page, hdr_oldest_snapshot) == 72, "hdr_oldest_snapshot offset mismatch"); +static_assert(offsetof(struct header_page, hdr_backup_pages) == 76, "hdr_backup_pages offset mismatch"); +static_assert(offsetof(struct header_page, hdr_crypt_page) == 80, "hdr_crypt_page offset mismatch"); +static_assert(offsetof(struct header_page, hdr_crypt_plugin) == 84, "hdr_crypt_plugin offset mismatch"); +static_assert(offsetof(struct header_page, hdr_att_high) == 116, "hdr_att_high offset mismatch"); +static_assert(offsetof(struct header_page, hdr_tra_high) == 120, "hdr_tra_high offset mismatch"); +static_assert(offsetof(struct header_page, hdr_data) == 128, "hdr_data offset mismatch"); + #define HDR_SIZE static_cast(offsetof(Ods::header_page, hdr_data[0])) // Header page clumplets @@ -492,6 +574,13 @@ struct page_inv_page UCHAR pip_bits[1]; }; +static_assert(sizeof(struct page_inv_page) == 32, "struct page_inv_page size mismatch"); +static_assert(offsetof(struct page_inv_page, pip_header) == 0, "pip_header offset mismatch"); +static_assert(offsetof(struct page_inv_page, pip_min) == 16, "pip_min offset mismatch"); +static_assert(offsetof(struct page_inv_page, pip_extent) == 20, "pip_extent offset mismatch"); +static_assert(offsetof(struct page_inv_page, pip_used) == 24, "pip_used offset mismatch"); +static_assert(offsetof(struct page_inv_page, pip_bits) == 28, "pip_bits offset mismatch"); + // SCN's Page @@ -502,6 +591,12 @@ struct scns_page ULONG scn_pages[1]; // SCN's vector }; +static_assert(sizeof(struct scns_page) == 24, "struct scns_page size mismatch"); +static_assert(offsetof(struct scns_page, scn_header) == 0, "scn_header offset mismatch"); +static_assert(offsetof(struct scns_page, scn_sequence) == 16, "scn_sequence offset mismatch"); +static_assert(offsetof(struct scns_page, scn_pages) == 20, "scn_pages offset mismatch"); + + // Important note ! // pagesPerPIP value must be multiply of pagesPerSCN value ! // @@ -544,6 +639,16 @@ struct pointer_page ULONG ppg_page[1]; // Data page vector }; +static_assert(sizeof(struct pointer_page) == 36, "struct pointer_page size mismatch"); +static_assert(offsetof(struct pointer_page, ppg_header) == 0, "ppg_header offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_sequence) == 16, "ppg_sequence offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_next) == 20, "ppg_next offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_count) == 24, "ppg_count offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_relation) == 26, "ppg_relation offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_min_space) == 28, "ppg_min_space offset mismatch"); +static_assert(offsetof(struct pointer_page, ppg_page) == 32, "ppg_page offset mismatch"); + + // pag_flags const UCHAR ppg_eof = 1; // Last pointer page in relation @@ -577,6 +682,11 @@ struct tx_inv_page UCHAR tip_transactions[1]; }; +static_assert(sizeof(struct tx_inv_page) == 24, "struct tx_inv_page size mismatch"); +static_assert(offsetof(struct tx_inv_page, tip_header) == 0, "tip_header offset mismatch"); +static_assert(offsetof(struct tx_inv_page, tip_next) == 16, "tip_next offset mismatch"); +static_assert(offsetof(struct tx_inv_page, tip_transactions) == 20, "tip_transactions offset mismatch"); + // Generator Page @@ -588,6 +698,12 @@ struct generator_page SINT64 gpg_values[1]; // Generator vector }; +static_assert(sizeof(struct generator_page) == 32, "struct generator_page size mismatch"); +static_assert(offsetof(struct generator_page, gpg_header) == 0, "gpg_header offset mismatch"); +static_assert(offsetof(struct generator_page, gpg_sequence) == 16, "gpg_sequence offset mismatch"); +static_assert(offsetof(struct generator_page, gpg_dummy1) == 20, "gpg_dummy1 offset mismatch"); +static_assert(offsetof(struct generator_page, gpg_values) == 24, "gpg_values offset mismatch"); + // Record header @@ -601,6 +717,14 @@ struct rhd UCHAR rhd_data[1]; // record data }; +static_assert(sizeof(struct rhd) == 16, "struct rhd size mismatch"); +static_assert(offsetof(struct rhd, rhd_transaction) == 0, "rhd_transaction offset mismatch"); +static_assert(offsetof(struct rhd, rhd_b_page) == 4, "rhd_b_page offset mismatch"); +static_assert(offsetof(struct rhd, rhd_b_line) == 8, "rhd_b_line offset mismatch"); +static_assert(offsetof(struct rhd, rhd_flags) == 10, "rhd_flags offset mismatch"); +static_assert(offsetof(struct rhd, rhd_format) == 12, "rhd_format offset mismatch"); +static_assert(offsetof(struct rhd, rhd_data) == 13, "rhd_data offset mismatch"); + #define RHD_SIZE static_cast(offsetof(Ods::rhd, rhd_data[0])) // Record header extended to hold long transaction id @@ -616,6 +740,15 @@ struct rhde UCHAR rhde_data[1]; // record data }; +static_assert(sizeof(struct rhde) == 20, "struct rhde size mismatch"); +static_assert(offsetof(struct rhde, rhde_transaction) == 0, "rhde_transaction offset mismatch"); +static_assert(offsetof(struct rhde, rhde_b_page) == 4, "rhde_b_page offset mismatch"); +static_assert(offsetof(struct rhde, rhde_b_line) == 8, "rhde_b_line offset mismatch"); +static_assert(offsetof(struct rhde, rhde_flags) == 10, "rhde_flags offset mismatch"); +static_assert(offsetof(struct rhde, rhde_format) == 12, "rhde_formats offset mismatch"); +static_assert(offsetof(struct rhde, rhde_tra_high) == 14, "rhde_tra_high offset mismatch"); +static_assert(offsetof(struct rhde, rhde_data) == 16, "rhde_data offset mismatch"); + #define RHDE_SIZE static_cast(offsetof(Ods::rhde, rhde_data[0])) // Record header for fragmented record @@ -633,6 +766,17 @@ struct rhdf UCHAR rhdf_data[1]; // record data }; +static_assert(sizeof(struct rhdf) == 24, "struct rhdf size mismatch"); +static_assert(offsetof(struct rhdf, rhdf_transaction) == 0, "rhdf_transaction offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_b_page) == 4, "rhdf_b_page offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_b_line) == 8, "rhdf_b_line offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_flags) == 10, "rhdf_flags offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_format) == 12, "rhdf_format offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_tra_high) == 14, "rhdf_tra_high offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_f_page) == 16, "rhdf_f_page offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_f_line) == 20, "rhdf_f_line offset mismatch"); +static_assert(offsetof(struct rhdf, rhdf_data) == 22, "rhdf_data offset mismatch"); + #define RHDF_SIZE static_cast(offsetof(Ods::rhdf, rhdf_data[0])) @@ -649,17 +793,29 @@ struct blh ULONG blh_length; // Total length of data USHORT blh_sub_type; // Blob sub-type UCHAR blh_charset; // Blob charset (since ODS 11.1) - UCHAR blh_unused; -#ifndef ODS_TESTING // Macro CHECK_BLOB_FIELD_ACCESS_FOR_SELECT is never defined, code under it was left for a case // we would like to have that check in a future. #ifdef CHECK_BLOB_FIELD_ACCESS_FOR_SELECT USHORT blh_fld_id; // Field ID #endif -#endif //ODS_TESTING + UCHAR blh_unused; ULONG blh_page[1]; // Page vector for blob pages }; +static_assert(sizeof(struct blh) == 32, "struct blh size mismatch"); +static_assert(offsetof(struct blh, blh_lead_page) == 0, "blh_lead_page offset mismatch"); +static_assert(offsetof(struct blh, blh_max_sequence) == 4, "blh_max_sequence offset mismatch"); +static_assert(offsetof(struct blh, blh_max_segment) == 8, "blh_max_segment offset mismatch"); +static_assert(offsetof(struct blh, blh_flags) == 10, "blh_flags offset mismatch"); +static_assert(offsetof(struct blh, blh_level) == 12, "blh_level offset mismatch"); +static_assert(offsetof(struct blh, blh_count) == 16, "blh_count offset mismatch"); +static_assert(offsetof(struct blh, blh_length) == 20, "blh_length offset mismatch"); +static_assert(offsetof(struct blh, blh_sub_type) == 24, "blh_sub_type offset mismatch"); +static_assert(offsetof(struct blh, blh_charset) == 26, "blh_charset offset mismatch"); +static_assert(offsetof(struct blh, blh_unused) == 27, "blh_unused offset mismatch"); +static_assert(offsetof(struct blh, blh_page) == 28, "blh_page offset mismatch"); + + #define BLH_SIZE static_cast(offsetof(Ods::blh, blh_page[0])) // rhd_flags, rhdf_flags and blh_flags @@ -691,6 +847,14 @@ struct Descriptor ULONG dsc_offset; }; +static_assert(sizeof(struct Descriptor) == 12, "struct Descriptor size mismatch"); +static_assert(offsetof(struct Descriptor, dsc_dtype) == 0, "dsc_dtype offset mismatch"); +static_assert(offsetof(struct Descriptor, dsc_scale) == 1, "dsc_scale offset mismatch"); +static_assert(offsetof(struct Descriptor, dsc_length) == 2, "dsc_length offset mismatch"); +static_assert(offsetof(struct Descriptor, dsc_sub_type) == 4, "dsc_sub_type offset mismatch"); +static_assert(offsetof(struct Descriptor, dsc_flags) == 6, "dsc_flags offset mismatch"); +static_assert(offsetof(struct Descriptor, dsc_offset) == 8, "dsc_offset offset mismatch"); + // Array description, "internal side" used by the engine. // And stored on the disk, in the relation summary blob. @@ -711,8 +875,24 @@ struct InternalArrayDesc SLONG iad_upper; // Upper bound }; iad_repeat iad_rpt[1]; + + static_assert(sizeof(struct iad_repeat) == 24, "struct iad_repeat size mismatch"); + static_assert(offsetof(struct iad_repeat, iad_desc) == 0, "iad_desc offset mismatch"); + static_assert(offsetof(struct iad_repeat, iad_length) == 12, "iad_length offset mismatch"); + static_assert(offsetof(struct iad_repeat, iad_lower) == 16, "iad_lower offset mismatch"); + static_assert(offsetof(struct iad_repeat, iad_upper) == 20, "iad_upper offset mismatch"); }; +static_assert(sizeof(struct InternalArrayDesc) == 40, "struct InternalArrayDesc size mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_version) == 0, "iad_version offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_dimensions) == 1, "iad_dimension offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_struct_count) == 2, "iad_struct_count offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_element_length) == 4, "iad_element_length offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_length) == 6, "iad_length offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_count) == 8, "iad_count offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_total_length) == 12, "iad_total_length offset mismatch"); +static_assert(offsetof(struct InternalArrayDesc, iad_rpt) == 16, "iad_rpt offset mismatch"); + const UCHAR IAD_VERSION_1 = 1; /* @@ -727,13 +907,10 @@ inline int IAD_LEN(int count) #define IAD_LEN(count) (sizeof (Ods::InternalArrayDesc) + \ (count ? count - 1: count) * sizeof (Ods::InternalArrayDesc::iad_repeat)) -#ifndef ODS_TESTING Firebird::string pagtype(UCHAR type); -#endif //ODS_TESTING } //namespace Ods -#ifndef ODS_TESTING // alignment for raw page access const USHORT PAGE_ALIGNMENT = 1024; @@ -745,6 +922,5 @@ const int MAX_TABLE_VERSIONS = 255; // max number of view formats (aka versions), limited by "SSHORT RDB$FORMAT" const int MAX_VIEW_VERSIONS = MAX_SSHORT; -#endif //ODS_TESTING #endif // JRD_ODS_H diff --git a/src/misc/ods.awk b/src/misc/ods.awk deleted file mode 100644 index 53b6bb6451..0000000000 --- a/src/misc/ods.awk +++ /dev/null @@ -1,112 +0,0 @@ -# -# PROGRAM: ODS sizes and offsets validation -# MODULE: ods.awk -# DESCRIPTION: Generates c++ code printing reference sample for ODS strctures -# -# The contents of this file are subject to the Initial -# Developer's Public License Version 1.0 (the "License"); -# you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# http://www.firebirdsql.org/en/initial-developer-s-public-license-version-1-0/ -# -# Software distributed under the License is distributed AS IS, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. -# See the License for the specific language governing rights -# and limitations under the License. -# -# The Original Code was created by Alexander Peshkoff -# for the Firebird Open Source RDBMS project. -# -# Copyright (c) 2018 Alexander Peshkoff -# and all contributors signed below. -# -# All Rights Reserved. -# Contributor(s): ______________________________________. -# - -BEGIN { - st = 0; - nm = ""; - nm2 = ""; - v2 = ""; - skip = 0; - - print "#include " - print "#ifdef _MSC_VER" - print "#include \"gen/autoconfig_msvc.h\"" - print "#else" - print "#include \"gen/autoconfig.h\"" - print "#endif" - print "" - print "#if SIZEOF_VOID_P == 8" - print "#define FMT \"l\"" - print "#else" - print "#define FMT \"\"" - print "#endif" - print "" - print "#include \"fb_types.h\"" - print "#define ODS_TESTING" - print "#include \"../jrd/ods.h\"" - print "" - print "using namespace Ods;" - print "" - print "int main() {" -} - -($1 == "struct") { - ++st; - if (st <= 2) - { - if (st == 1) - { - nm = $2; - nm2 = nm; - } - else - { - nm2 = nm "::" $2; - } - v2 = $2 "_"; - - print "\tprintf(\"\\n *** " $0 " %\" FMT \"u\\n\", sizeof(" nm2 "));"; - print "\t" nm2 " " v2 ";"; - } -} - - -($1 == "};") { - if (st > 1) - { - v2 = nm "_"; - } - st--; -} - -($1 == "}") { - if (st > 1) - { - st--; - v2 = nm "_"; - } -} - -($2 == "ODS_TESTING") { skip = 1; } - -(st > 0 && substr($1, 1, 1) != "#" && $1 != "struct" && skip == 0 && $1 != "//") { - m = $2; - i = index(m, "["); - if (i == 0) - i = index(m, ";"); - if (i > 0) - m = substr(m, 1, i - 1); - - if (length(m) > 0) - print "\tprintf(\"" m " %\" FMT \"d\\n\", (char*)&" v2 "." m " - (char*)&" v2 ");" -} - -($2 == "//ODS_TESTING") { skip = 0; } - -END { - print "}" -} - diff --git a/src/misc/ods.txt b/src/misc/ods.txt deleted file mode 100644 index 101bde4278..0000000000 --- a/src/misc/ods.txt +++ /dev/null @@ -1,185 +0,0 @@ - - *** struct pag 16 -pag_type 0 -pag_flags 1 -pag_reserved 2 -pag_generation 4 -pag_scn 8 -pag_pageno 12 - - *** struct blob_page 32 -blp_header 0 -blp_lead_page 16 -blp_sequence 20 -blp_length 24 -blp_pad 26 -blp_page 28 - - *** struct btree_page 40 -btr_header 0 -btr_sibling 16 -btr_left_sibling 20 -btr_prefix_total 24 -btr_relation 28 -btr_length 30 -btr_id 32 -btr_level 33 -btr_jump_interval 34 -btr_jump_size 36 -btr_jump_count 38 -btr_nodes 39 - - *** struct data_page 28 -dpg_header 0 -dpg_sequence 16 -dpg_relation 20 -dpg_count 22 - - *** struct dpg_repeat 4 -dpg_offset 0 -dpg_length 2 -dpg_rpt 24 - - *** struct index_root_page 32 -irt_header 0 -irt_relation 16 -irt_count 18 - - *** struct irt_repeat 12 -irt_root 0 -irt_transaction 4 -irt_desc 8 -irt_keys 10 -irt_flags 11 -irt_rpt 20 - - *** struct irtd 8 -irtd_field 0 -irtd_itype 2 -irtd_selectivity 4 - - *** struct header_page 132 -hdr_header 0 -hdr_page_size 16 -hdr_ods_version 18 -hdr_PAGES 20 -hdr_next_page 24 -hdr_oldest_transaction 28 -hdr_oldest_active 32 -hdr_next_transaction 36 -hdr_sequence 40 -hdr_flags 42 -hdr_creation_date 44 -hdr_attachment_id 52 -hdr_shadow_count 56 -hdr_cpu 60 -hdr_os 61 -hdr_cc 62 -hdr_compatibility_flags 63 -hdr_ods_minor 64 -hdr_end 66 -hdr_page_buffers 68 -hdr_oldest_snapshot 72 -hdr_backup_pages 76 -hdr_crypt_page 80 -hdr_crypt_plugin 84 -hdr_att_high 116 -hdr_tra_high 120 -hdr_data 128 - - *** struct page_inv_page 32 -pip_header 0 -pip_min 16 -pip_extent 20 -pip_used 24 -pip_bits 28 - - *** struct scns_page 24 -scn_header 0 -scn_sequence 16 -scn_pages 20 - - *** struct pointer_page 36 -ppg_header 0 -ppg_sequence 16 -ppg_next 20 -ppg_count 24 -ppg_relation 26 -ppg_min_space 28 -ppg_page 32 - - *** struct tx_inv_page 24 -tip_header 0 -tip_next 16 -tip_transactions 20 - - *** struct generator_page 32 -gpg_header 0 -gpg_sequence 16 -gpg_dummy1 20 -gpg_values 24 - - *** struct rhd 16 -rhd_transaction 0 -rhd_b_page 4 -rhd_b_line 8 -rhd_flags 10 -rhd_format 12 -rhd_data 13 - - *** struct rhde 20 -rhde_transaction 0 -rhde_b_page 4 -rhde_b_line 8 -rhde_flags 10 -rhde_format 12 -rhde_tra_high 14 -rhde_data 16 - - *** struct rhdf 24 -rhdf_transaction 0 -rhdf_b_page 4 -rhdf_b_line 8 -rhdf_flags 10 -rhdf_format 12 -rhdf_tra_high 14 -rhdf_f_page 16 -rhdf_f_line 20 -rhdf_data 22 - - *** struct blh 32 -blh_lead_page 0 -blh_max_sequence 4 -blh_max_segment 8 -blh_flags 10 -blh_level 12 -blh_count 16 -blh_length 20 -blh_sub_type 24 -blh_charset 26 -blh_unused 27 -blh_page 28 - - *** struct Descriptor 12 -dsc_dtype 0 -dsc_scale 1 -dsc_length 2 -dsc_sub_type 4 -dsc_flags 6 -dsc_offset 8 - - *** struct InternalArrayDesc 40 -iad_version 0 -iad_dimensions 1 -iad_struct_count 2 -iad_element_length 4 -iad_length 6 -iad_count 8 -iad_total_length 12 - - *** struct iad_repeat 24 -iad_desc 0 -iad_length 12 -iad_lower 16 -iad_upper 20 -iad_rpt 16 From 4fb0dfb6554fb74925d6f06d73e59dab9564e336 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 15 Jan 2020 00:04:26 +0000 Subject: [PATCH 13/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index f9937727b1..7c1443a4dd 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1723 + FORMAL BUILD NUMBER:1726 */ -#define PRODUCT_VER_STRING "4.0.0.1723" -#define FILE_VER_STRING "WI-T4.0.0.1723" -#define LICENSE_VER_STRING "WI-T4.0.0.1723" -#define FILE_VER_NUMBER 4, 0, 0, 1723 +#define PRODUCT_VER_STRING "4.0.0.1726" +#define FILE_VER_STRING "WI-T4.0.0.1726" +#define LICENSE_VER_STRING "WI-T4.0.0.1726" +#define FILE_VER_NUMBER 4, 0, 0, 1726 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1723" +#define FB_BUILD_NO "1726" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 73bb6e26c3..97e03e1981 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1723 +BuildNum=1726 NowAt=`pwd` cd `dirname $0` From 9164797892708585cc804b36ac7a4c2cbbfde064 Mon Sep 17 00:00:00 2001 From: Dimitry Sibiryakov Date: Wed, 15 Jan 2020 14:50:18 +0100 Subject: [PATCH 14/39] Refined Windows package creation (#251) --- .../win32/After_Installation.url | 2 +- .../win32/BuildExecutableInstall.bat | 408 +++++++----------- .../arch-specific/win32/FirebirdInstall.iss | 188 +++----- .../arch-specific/win32/Readme_DEV.txt | 2 + .../arch-specific/win32/i18n_readme.txt | 2 +- builds/install/misc/firebird.conf.in | 2 +- builds/win32/make_all.bat | 3 +- builds/win32/make_boot.bat | 2 +- builds/win32/make_examples.bat | 90 ++-- builds/win32/setenvvar.bat | 8 - configure.ac | 3 - src/CMakeLists.txt | 2 +- 12 files changed, 284 insertions(+), 428 deletions(-) diff --git a/builds/install/arch-specific/win32/After_Installation.url b/builds/install/arch-specific/win32/After_Installation.url index 430c312307..c5d29c42a6 100644 --- a/builds/install/arch-specific/win32/After_Installation.url +++ b/builds/install/arch-specific/win32/After_Installation.url @@ -1,2 +1,2 @@ [InternetShortcut] -URL=http://www.firebirdsql.org/afterinstall/$MAJOR$MINOR$RELEASE \ No newline at end of file +URL=http://www.firebirdsql.org/afterinstall/{#FB_MAJOR_VER}{#FB_MINOR_VER}{#FB_REV_NO} diff --git a/builds/install/arch-specific/win32/BuildExecutableInstall.bat b/builds/install/arch-specific/win32/BuildExecutableInstall.bat index db2b0426aa..2c0ba91ce9 100644 --- a/builds/install/arch-specific/win32/BuildExecutableInstall.bat +++ b/builds/install/arch-specific/win32/BuildExecutableInstall.bat @@ -22,6 +22,8 @@ ::============================================================================ :SET_PARAMS +::========= + @echo off :: reset ERRLEV to clear error from last run in same cmd shell set ERRLEV=0 @@ -35,21 +37,6 @@ set FBBUILD_ISX_PACK=0 if not defined FB2_SNAPSHOT (set FB2_SNAPSHOT=0) -:: Set our package number at 0 and increment every -:: time we rebuild in a single session -if not defined FBBUILD_PACKAGE_NUMBER ( -set FBBUILD_PACKAGE_NUMBER=0 -) else ( -set /A FBBUILD_PACKAGE_NUMBER+=1 -) -@echo Setting FBBUILD_PACKAGE_NUMBER to %FBBUILD_PACKAGE_NUMBER% - -::If a suffix is defined (usually for an RC) ensure it is prefixed correctly. -if defined FBBUILD_FILENAME_SUFFIX ( -if not "%FBBUILD_FILENAME_SUFFIX:~0,1%"=="_" ( -(set FBBUILD_FILENAME_SUFFIX=_%FBBUILD_FILENAME_SUFFIX%) -) -) :: See what we have on the command line @@ -61,39 +48,12 @@ for %%v in ( %* ) do ( ( if /I "%%v"=="ALL" ( (set FBBUILD_ZIP_PACK=1) & (set FBBUILD_ISX_PACK=1) ) ) ) -:: Now check whether we are debugging the InnoSetup script - -@if %FB2_ISS_DEBUG% equ 0 (@set ISS_BUILD_TYPE=iss_release) else (@set ISS_BUILD_TYPE=iss_debug) -@if %FB2_ISS_DEBUG% equ 0 (@set ISS_COMPRESS=compression) else (@set ISS_COMPRESS=nocompression) - -(@set ISS_EXAMPLES=examples) -@if %FB2_ISS_DEBUG% equ 1 ( - @if %FB2_EXAMPLES% equ 0 (@set ISS_EXAMPLES=noexamples) -) - ::Are we doing a snapshot build? If so we always do less work. if "%FB2_SNAPSHOT%"=="1" ( - (set FB_ISS_EXAMPLES=noexamples) (set FBBUILD_ISX_PACK=0) ) -:: Set up our final destination -set FBBUILD_INSTALL_IMAGES=%FB_ROOT_PATH%\builds\install_images -if not exist %FBBUILD_INSTALL_IMAGES% (mkdir %FBBUILD_INSTALL_IMAGES%) - - - -:: Determine Product Status -set FBBUILD_PROD_STATUS= -@type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr /I UNSTABLE > nul && ( -set FBBUILD_PROD_STATUS=DEV) || type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr /I ALPHA > nul && ( -set FBBUILD_PROD_STATUS=DEV) || type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr /I BETA > nul && ( -set FBBUILD_PROD_STATUS=PROD) || type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr /I "Release Candidate" > nul && ( -set FBBUILD_PROD_STATUS=PROD) || type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr "RC" > nul && ( -set FBBUILD_PROD_STATUS=PROD) || type %FB_ROOT_PATH%\src\jrd\build_no.h | findstr /I "Final" > nul && ( -set FBBUILD_PROD_STATUS=PROD) - ::End of SET_PARAMS ::----------------- @goto :EOF @@ -110,6 +70,19 @@ set FBBUILD_PROD_STATUS=PROD) @echo o Checking for unix2dos... (cmd /c "unix2dos.exe --version 2>&1 | findstr version > nul" ) || ( call :ERROR Could not locate unix2dos && @goto :EOF ) +@for /f "usebackq tokens=*" %%c in (`where /f touch 2^>nul`) do set TOUCH_COMMAND=%%c +if defined TOUCH_COMMAND ( + @%TOUCH_COMMAND% --version nul 2>nul + if not errorlevel 1 ( + @echo o POSIX touch utility found at %TOUCH_COMMAND% + ) else ( @set TOUCH_COMMAND= ) +) + +@for /f "usebackq tokens=*" %%c in (`where /f md5sum 2^>nul`) do set MD5_COMMAND=%%c +if defined MD5_COMMAND ( + @echo o POSIX md5sum utility found at %MD5_COMMAND% +) + if %FBBUILD_ZIP_PACK% EQU 1 ( if not defined SEVENZIP ( call :ERROR SEVENZIP environment variable is not defined. @@ -117,33 +90,40 @@ if %FBBUILD_ZIP_PACK% EQU 1 ( ) else (@echo o Compression utility found.) ) +if %FBBUILD_ISX_PACK% NEQ 1 goto :SKIP_INNO -if %FBBUILD_ISX_PACK% EQU 1 ( - if NOT DEFINED INNO5_SETUP_PATH ( - call :ERROR INNO5_SETUP_PATH variable not defined - @goto :EOF - ) else ( - @echo o Inno Setup found at %INNO5_SETUP_PATH%. - ) +if defined INNO5_SETUP_PATH ( + set ISCC_COMMAND=%INNO5_SETUP_PATH%\iscc.exe ) +:: If the environment variable is not set let's search in PATH +if not defined ISCC_COMMAND ( + @for /f "usebackq tokens=*" %%c in (`where /f iscc 2^>nul`) do set ISCC_COMMAND=%%c +) +if not defined ISCC_COMMAND ( + @echo Required Inno Setup compiler not found + @exit /b 1 +) +@echo o Inno Setup found as %ISCC_COMMAND%. + +:SKIP_INNO if not defined WIX ( - call :ERROR WIX not defined. WiX is needed to build the MSI kits of the CRT runtimes. - @goto :EOF + @echo. + @echo The WIX environment var not defined. + @echo WiX is needed to build the MSI kits of the CRT runtimes. + @echo. ) else ( @echo o WiX found at "%WIX%". ) -if not DEFINED FB_EXTERNAL_DOCS ( +if not defined FB_EXTERNAL_DOCS ( @echo. @echo The FB_EXTERNAL_DOCS environment var is not defined @echo It should point to the directory containing the relevant release notes @echo in adobe pdf format. @echo. - @echo Subsequent script execution will be cancelled. - @echo. - cancel_script > nul 2>&1 - goto :EOF +) else ( + @echo o Package will include documentation from "%FB_EXTERNAL_DOCS%". ) @@ -152,94 +132,69 @@ if not DEFINED FB_EXTERNAL_DOCS ( @goto :EOF -:SED_MAGIC -:: Do some sed magic to make sure that the final product -:: includes the version string in the filename. -:: If the Firebird Unix tools for Win32 aren't on -:: the path this will fail! Use of the cygwin tools has not -:: been tested and may produce unexpected results. -::======================================================== -find "#define PRODUCT_VER_STRING" %FB_ROOT_PATH%\src\jrd\build_no.h > %temp%.\b$1.txt -sed -n -e s/\"//g -e s/"#define PRODUCT_VER_STRING "//w%temp%.\b$2.txt %temp%.\b$1.txt -for /f "tokens=*" %%a in ('type %temp%.\b$2.txt') do set FBBUILD_PRODUCT_VER_STRING=%%a +:SET_VERSION +::========== -find "#define FB_MAJOR_VER" %FB_ROOT_PATH%\src\jrd\build_no.h > %temp%.\b$1.txt -sed -n -e s/\"//g -e s/"#define FB_MAJOR_VER "//w%temp%.\b$2.txt %temp%.\b$1.txt -for /f "tokens=*" %%a in ('type %temp%.\b$2.txt') do set FB_MAJOR_VER=%%a +:: Cut off everything that is not #define to let Inno Setup use it +findstr /B /L "#define" "%FB_ROOT_PATH%\src\jrd\build_no.h" >"%FB_ROOT_PATH%\gen\jrd\build_no.h" +:: Read version parameters from build_no.h +for /F "tokens=2*" %%a in (%FB_ROOT_PATH%\gen\jrd\build_no.h) do ( +@echo Setting %%a to %%~b +SET %%a=%%~b +) -find "#define FB_MINOR_VER" %FB_ROOT_PATH%\src\jrd\build_no.h > %temp%.\b$1.txt -sed -n -e s/\"//g -e s/"#define FB_MINOR_VER "//w%temp%.\b$2.txt %temp%.\b$1.txt -for /f "tokens=*" %%a in ('type %temp%.\b$2.txt') do set FB_MINOR_VER=%%a +:: Set our package number at 0 and increment every +:: time we rebuild in a single session +if not defined FBBUILD_PACKAGE_NUMBER ( +set FBBUILD_PACKAGE_NUMBER=0 +) else ( +set /A FBBUILD_PACKAGE_NUMBER+=1 +) +@echo Setting FBBUILD_PACKAGE_NUMBER to %FBBUILD_PACKAGE_NUMBER% -find "#define FB_REV_NO" %FB_ROOT_PATH%\src\jrd\build_no.h > %temp%.\b$1.txt -sed -n -e s/\"//g -e s/"#define FB_REV_NO "//w%temp%.\b$2.txt %temp%.\b$1.txt -for /f "tokens=*" %%a in ('type %temp%.\b$2.txt') do set FB_REV_NO=%%a +:: If a suffix is defined (usually for an RC) ensure it is prefixed correctly. +if defined FBBUILD_FILENAME_SUFFIX ( +if not "%FBBUILD_FILENAME_SUFFIX:~0,1%"=="_" ( +(set FBBUILD_FILENAME_SUFFIX=_%FBBUILD_FILENAME_SUFFIX%) +) +) -find "#define FB_BUILD_NO" %FB_ROOT_PATH%\src\jrd\build_no.h > %temp%.\b$1.txt -sed -n -e s/\"//g -e s/"#define FB_BUILD_NO "//w%temp%.\b$2.txt %temp%.\b$1.txt -for /f "tokens=*" %%a in ('type %temp%.\b$2.txt') do set FB_BUILD_NO=%%a +:: Set up our final destination +set FBBUILD_INSTALL_IMAGES=%FB_ROOT_PATH%\builds\install_images +if not exist "%FBBUILD_INSTALL_IMAGES%" (mkdir "%FBBUILD_INSTALL_IMAGES%") -set FBBUILD_FILE_ID=%FBBUILD_PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER%_%FB_TARGET_PLATFORM% +:: Determine Product Status +if %FB_BUILD_TYPE%==V ( +set FBBUILD_PROD_STATUS=PROD +) else ( +set FBBUILD_PROD_STATUS=DEV +) -::@echo s/-2.0.0-/-%FBBUILD_PRODUCT_VER_STRING%-/ > %temp%.\b$3.txt -@echo s/define release/define %FBBUILD_BUILDTYPE%/ > %temp%.\b$3.txt -@echo s/define no_pdb/define %FBBUILD_SHIP_PDB%/ >> %temp%.\b$3.txt -::@echo s/define package_number=\"0\"/define package_number=\"%FBBUILD_PACKAGE_NUMBER%\"/ >> %temp%.\b$3.txt -@echo s/define iss_release/define %ISS_BUILD_TYPE%/ >> %temp%.\b$3.txt -@echo s/define examples/define %ISS_EXAMPLES%/ >> %temp%.\b$3.txt -@echo s/define compression/define %ISS_COMPRESS%/ >> %temp%.\b$3.txt -@echo s/FBBUILD_PRODUCT_VER_STRING/%FBBUILD_PRODUCT_VER_STRING%/ >> %temp%.\b$3.txt +set FBBUILD_FILE_ID=%PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER%_%FB_TARGET_PLATFORM% -sed -f %temp%.\b$3.txt FirebirdInstall.iss > FirebirdInstall_%FBBUILD_FILE_ID%.iss - -:: This is a better way of achieving what is done in make_all.bat, but we don't -:: test for sed in that script. -@sed /@UDF_COMMENT@/s/@UDF_COMMENT@/#/ < %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in > %FB_OUTPUT_DIR%\firebird.conf - -set FBBUILD_FB40_CUR_VER=%FB_MAJOR_VER%.%FB_MINOR_VER%.%FB_REV_NO% -set FBBUILD_FB_CUR_VER=%FBBUILD_FB40_CUR_VER% -set FBBUILD_FB_LAST_VER=%FBBUILD_FB30_CUR_VER% - -:: Now set some version strings of our legacy releases. -:: This helps us copy the correct documentation, -:: as well as set up the correct shortcuts -set FBBUILD_FB15_CUR_VER=1.5.6 -set FBBUILD_FB20_CUR_VER=2.0.7 -set FBBUILD_FB21_CUR_VER=2.1.7 -set FBBUILD_FB25_CUR_VER=2.5.8 -set FBBUILD_FB30_CUR_VER=3.0.4 - -:: Now fix up the major.minor version strings in the readme files. -:: We place output in %FB_GEN_DIR%\readmes +@setlocal +@echo. @if not exist %FB_GEN_DIR%\readmes (@mkdir %FB_GEN_DIR%\readmes) -@for %%d in (ba cz de es fr hu it pl pt ru si ) do ( - @if not exist %FB_GEN_DIR%\readmes\%%d ( - @mkdir %FB_GEN_DIR%\readmes\%%d - ) -) - -@echo s/\$MAJOR/%FB_MAJOR_VER%/g > %temp%.\b$4.txt -@echo s/\$MINOR/%FB_MINOR_VER%/g >> %temp%.\b$4.txt -@echo s/\$RELEASE/%FB_REV_NO%/g >> %temp%.\b$4.txt -@echo %FBBUILD_PROD_STATUS% release. Copying Readme_%FBBUILD_PROD_STATUS%.txt Readme.txt -@copy Readme_%FBBUILD_PROD_STATUS%.txt Readme.txt -@for %%f in (Readme.txt installation_readme.txt After_Installation.url) do ( +set SED_COMMAND=sed -e s/\$MAJOR/%FB_MAJOR_VER%/g ^ + -e s/\$MINOR/%FB_MINOR_VER%/g ^ + -e s/\$RELEASE/%FB_REV_NO%/g +@echo Processing version strings in Readme_%FBBUILD_PROD_STATUS%.txt +@%SED_COMMAND% Readme_%FBBUILD_PROD_STATUS%.txt > %FB_GEN_DIR%\readmes\Readme.txt +@for %%f in (installation_readme.txt) do ( @echo Processing version strings in %%f - @sed -f %temp%.\b$4.txt %%f > %FB_GEN_DIR%\readmes\%%f + @%SED_COMMAND% %%f > %FB_GEN_DIR%\readmes\%%f ) @for %%d in (ba cz de es fr hu it pl pt ru si ) do ( - @pushd %%d - @for /F %%f in ( '@dir /B /A-D *.txt' ) do ( - @echo Processing version strings in %%d\%%f - @sed -f %temp%.\b$4.txt %%f > %FB_GEN_DIR%\readmes\%%d\%%f + @if not exist %FB_GEN_DIR%\readmes\%%d (@mkdir %FB_GEN_DIR%\readmes\%%d) + @for %%f in ( %%d\*.txt ) do ( + @echo Processing version strings in %%f + @%SED_COMMAND% %%f > %FB_GEN_DIR%\readmes\%%f ) - @popd ) -del %temp%.\b$?.txt +@endlocal - -::End of SED_MAGIC +::End of SET_VERSION ::---------------- @goto :EOF @@ -268,14 +223,14 @@ if %MSVC_VERSION% EQU 15 ( ) for %%f in ( msvcp%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_0%.dll vcruntime%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_0%.dll ) do ( echo Copying "%VCToolsRedistDir%\%VSCMD_ARG_TGT_ARCH%\Microsoft.VC%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_1%.CRT\%%f" - copy "%VCToolsRedistDir%\%VSCMD_ARG_TGT_ARCH%\Microsoft.VC%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_1%.CRT\%%f" %FB_OUTPUT_DIR%\ + copy "%VCToolsRedistDir%\%VSCMD_ARG_TGT_ARCH%\Microsoft.VC%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_1%.CRT\%%f" %FB_OUTPUT_DIR%\ >nul if %ERRORLEVEL% GEQ 1 ( call :ERROR Copying "%VCToolsRedistDir%\%VSCMD_ARG_TGT_ARCH%\Microsoft.VC%MSVC_RUNTIME_MAJOR_VERSION%%MSVC_RUNTIME_MINOR_VERSION_1%.CRT\%%f" failed with error %ERRORLEVEL% ) && (goto :EOF) ) ) -@implib.exe | findstr "Borland" > nul -@if errorlevel 0 ( +@where /Q implib.exe +@if not errorlevel 1 ( if "%VSCMD_ARG_TGT_ARCH%"=="x86" ( @echo Generating fbclient_bor.lib @implib %FB_OUTPUT_DIR%\lib\fbclient_bor.lib %FB_OUTPUT_DIR%\fbclient.dll > nul @@ -325,13 +280,8 @@ mkdir %FB_OUTPUT_DIR%\misc\upgrade\security 2>nul goto :EOF ) - @echo Copying other documentation... @copy %FB_GEN_DIR%\readmes\installation_readme.txt %FB_OUTPUT_DIR%\doc\installation_readme.txt > nul -:: WhatsNew doesn't exist at the moment (Alpha1) - perhaps it will turn up later in the release cycle. -:: In any case, if it is not an error if it doesn't exist -@ren %FB_OUTPUT_DIR%\doc\WhatsNew %FB_OUTPUT_DIR%\doc\WhatsNew.txt - :: FIX ME - we now have some .md files and ChangeLog is no longer a monster. :: Maybe we can just do nothing here. @@ -342,7 +292,6 @@ mkdir %FB_OUTPUT_DIR%\misc\upgrade\security 2>nul :: @copy %FB_ROOT_PATH%\ChangeLog %FB_OUTPUT_DIR%\doc\ChangeLog.txt > nul ::) - @mkdir %FB_OUTPUT_DIR%\doc\sql.extensions 2>nul @if %ERRORLEVEL% GEQ 2 ( (call :ERROR MKDIR for doc\sql.extensions dir failed) & (@goto :EOF)) @copy %FB_ROOT_PATH%\doc\sql.extensions\*.* %FB_OUTPUT_DIR%\doc\sql.extensions\ > nul @@ -353,7 +302,7 @@ mkdir %FB_OUTPUT_DIR%\misc\upgrade\security 2>nul :: if the docs are available then we can include them. if defined FB_EXTERNAL_DOCS ( @echo Copying pdf docs... -@for %%v in ( Firebird-%FB_MAJOR_VER%.%FB_MINOR_VER%-QuickStart.pdf Firebird_v%FBBUILD_FB_CUR_VER%.ReleaseNotes.pdf ) do ( +@for %%v in ( Firebird-%FB_MAJOR_VER%.%FB_MINOR_VER%-QuickStart.pdf Firebird_v%FB_MAJOR_VER%.%FB_MINOR_VER%.%FB_REV_NO%.ReleaseNotes.pdf ) do ( @echo ... %%v (@copy /Y %FB_EXTERNAL_DOCS%\%%v %FB_OUTPUT_DIR%\doc\%%v > nul) || (call :WARNING Copying %FB_EXTERNAL_DOCS%\%%v failed.) ) @@ -361,42 +310,46 @@ if defined FB_EXTERNAL_DOCS ( @echo. ) +@echo Cleaning irrelevant files... :: Clean out text notes that are either not relevant to Windows or :: are only of use to engine developers. @for %%v in ( README.makefiles README.user.embedded README.user.troubleshooting README.build.mingw.html README.build.msvc.html fb2-todo.txt cleaning-todo.txt install_win32.txt README.coding.style emacros-cross_ref.html firebird_conf.txt *.*~) do ( @del %FB_OUTPUT_DIR%\doc\%%v 2>nul ) +@echo Copy license... :: Add license for %%v in (IPLicense.txt IDPLicense.txt ) do ( @copy %FB_ROOT_PATH%\builds\install\misc\%%v %FB_OUTPUT_DIR%\%%v > nul ) :: And readme -@copy %FB_GEN_DIR%\readmes\readme.txt %FB_OUTPUT_DIR%\ > nul +@copy %FB_GEN_DIR%\readmes\Readme.txt %FB_OUTPUT_DIR%\ > nul :: Walk through all docs and transform any that are not .txt, .pdf or .html to .txt @echo Setting .txt filetype to ascii docs. -for /R %FB_OUTPUT_DIR%\doc %%v in (.) do ( - pushd %%v - for /F %%W in ( 'dir /B /A-D' ) do ( - if /I "%%~xW" NEQ ".txt" ( - if /I "%%~xW" NEQ ".pdf" ( - if /I "%%~xW" NEQ ".htm" ( - if /I "%%~xW" NEQ ".html" ( - ren %%W %%W.txt +for /R %FB_OUTPUT_DIR%\doc %%v in ( * ) do ( + if /I not "%%~xv" == ".md" ( + if /I not "%%~xv" == ".txt" ( + if /I not "%%~xv" == ".pdf" ( + if /I not "%%~xv" == ".htm" ( + if /I not "%%~xv" == ".html" ( + ren %%v %%~nxv.txt ) ) ) ) ) - popd ) -:: Throw away any errorlevel left hanging around -@set | findstr win > nul +if %FB2_SNAPSHOT% EQU 1 ( + @copy %FB_ROOT_PATH%\builds\install\arch-specific\win32\readme_snapshot.txt %FB_OUTPUT_DIR%\readme_snapshot.txt > nul +) @echo Completed copying docs. + +:: Examples were already copied by make_examples + ::End of COPY_XTRA ::---------------- @goto :EOF @@ -426,6 +379,7 @@ if %MSVC_VERSION% EQU 15 ( :INCLUDE_DIR +::========== :: Prepare other files needed for deployment to /include dir setlocal :: grab some missing bits'n'pieces from different parts of the source tree @@ -437,8 +391,8 @@ setlocal @echo Copying other include files required for development... set OUTPATH=%FB_OUTPUT_DIR%\include @copy %FB_ROOT_PATH%\src\yvalve\perf.h %OUTPATH%\ > nul -@copy %FB_ROOT_PATH%\src\include\gen\firebird.pas %OUTPATH%\firebird\ > nul || (@call :ERROR Failure executing copy %FB_ROOT_PATH%\src\include\gen\firebird.pas %OUTPATH%\firebird\ && @goto :EOF ) -@xcopy /e /i /y %FB_ROOT_PATH%\src\include\firebird\impl %OUTPATH%\firebird\ > nul || (@call :ERROR Failure executing @xcopy /e /i /y %FB_ROOT_PATH%\src\include\firebird\* %OUTPATH%\firebird\ && @goto :EOF ) +@copy %FB_ROOT_PATH%\src\include\gen\firebird.pas %OUTPATH%\firebird\ > nul || (@call :ERROR Failure executing copy %FB_ROOT_PATH%\src\include\gen\firebird.pas %OUTPATH%\firebird\ ) +@xcopy /e /i /y %FB_ROOT_PATH%\src\include\firebird\impl %OUTPATH%\firebird\ > nul || (@call :ERROR Failure executing @xcopy /e /i /y %FB_ROOT_PATH%\src\include\firebird\* %OUTPATH%\firebird\ ) @if %ERRLEV% GEQ 1 goto :END endlocal @@ -494,85 +448,40 @@ copy %FB_ROOT_PATH%\builds\install\misc\databases.conf.in %FB_OUTPUT_DIR%\databa :: Get a list of all files in the tree make sure :: that and they all have windows EOL ::=============================================== -for /F %%W in ( 'dir %FB_OUTPUT_DIR% /b /a-d /s' ) do ( - for %%X in ( txt conf sql c cpp hpp h bat pas e def rc md ) do ( - if /I "%%~xW" EQU ".%%X" ( unix2dos --u2d --safe %%W 2>nul >nul ) - ) +for /R %FB_OUTPUT_DIR% %%W in ( *.txt *.conf *.sql *.c *.cpp *.hpp *.h *.bat *.pas *.e *.def *.rc *.md *.html ) do ( + unix2dos -q --safe %%W || exit /b 1 ) + ::End of SET_CRLF ::------------- @goto :EOF -:GEN_ZIP -::====== -if %FBBUILD_ZIP_PACK% EQU 0 goto :EOF -@echo - Generate the directory tree to be zipped -set FBBUILD_ZIP_PACK_ROOT=%FB_ROOT_PATH%\builds\zip_pack_%FB_TARGET_PLATFORM% -if not exist %FBBUILD_ZIP_PACK_ROOT% @mkdir %FBBUILD_ZIP_PACK_ROOT% 2>nul -@del /s /q %FBBUILD_ZIP_PACK_ROOT%\ > nul -::@copy /Y %FB_OUTPUT_DIR% %FBBUILD_ZIP_PACK_ROOT% > nul -::for %%v in (doc doc\sql.extensions help include intl lib udf misc misc\upgrade\security plugins system32 ) do ( -:: @mkdir %FBBUILD_ZIP_PACK_ROOT%\%%v 2>nul -:: @dir /b /a-d /s %FB_OUTPUT_DIR%\%%v\*.* >nul 2>nul -:: if not ERRORLEVEL 1 @copy /Y %FB_OUTPUT_DIR%\%%v\*.* %FBBUILD_ZIP_PACK_ROOT%\%%v\ > nul -::) -@xcopy /Y /E /S %FB_OUTPUT_DIR% %FBBUILD_ZIP_PACK_ROOT% > nul - -@echo - Add examples to zip tree -@xcopy /Y /E /S %FB_OUTPUT_DIR%\examples\*.* %FBBUILD_ZIP_PACK_ROOT%\examples > nul -::@if %FB2_EXAMPLES% equ 1 for %%v in (examples examples\api examples\build_win32 examples\dbcrypt examples\empbuild examples\include examples\interfaces examples\package examples\stat examples\udf examples\udr ) do ( -:: @mkdir %FBBUILD_ZIP_PACK_ROOT%\%%v 2>nul -:: dir %FB_OUTPUT_DIR%\%%v\*.* > nul 2>nul -:: if not ERRORLEVEL 1 @copy /Y %FB_OUTPUT_DIR%\%%v\*.* %FBBUILD_ZIP_PACK_ROOT%\%%v\ > nul -::) - - -@echo - Now remove stuff from zip tree that is not needed... -setlocal -set FB_RM_FILE_LIST=doc\installation_readme.txt system32\vccrt%MSVC_VERSION%_%FB_TARGET_PLATFORM%.wixpdb icudt52l_empty.dat -for %%v in ( %FB_RM_FILE_LIST% ) do ( - @del %FBBUILD_ZIP_PACK_ROOT%\%%v > nul 2>&1 -) -endlocal - -if %FB2_SNAPSHOT% EQU 1 ( - @copy %FB_ROOT_PATH%\builds\install\arch-specific\win32\readme_snapshot.txt %FBBUILD_ZIP_PACK_ROOT%\readme_snapshot.txt > nul -) - -if not "%FBBUILD_SHIP_PDB%"=="ship_pdb" ( - @del /q %FBBUILD_ZIP_PACK_ROOT%\*.pdb > nul 2>&1 -) - -rmdir /s /q %FBBUILD_ZIP_PACK_ROOT%\examples\build_unix - -:: Don't grab old install notes for zip pack - document needs a complete re-write. -::@copy %FB_ROOT_PATH%\doc\install_win32.txt %FBBUILD_ZIP_PACK_ROOT%\doc\README_installation.txt > nul - -::End of GEN_ZIP -::-------------- -goto :EOF - - :ZIP_PACK ::======= -if %FBBUILD_ZIP_PACK% EQU 0 goto :EOF -if "%FBBUILD_SHIP_PDB%" == "ship_pdb" ( - if exist %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%_pdb%FBBUILD_FILENAME_SUFFIX%.zip ( - @del %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%_pdb%FBBUILD_FILENAME_SUFFIX%.zip - ) - set FBBUILD_ZIPFILE=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%_pdb%FBBUILD_FILENAME_SUFFIX%.zip +:: Forcefully disable delayed expansion because of exclamation marks in 7z switches +setlocal DisableDelayedExpansion +set SKIP_FILES=-x!installation_readme.txt + +if "%FBBUILD_SHIP_PDB%" == "ship_pdb" ( + set FBBUILD_ZIPFILE=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%_pdb%FBBUILD_FILENAME_SUFFIX%.zip ) else ( - if exist %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.zip ( - @del %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.zip - ) set FBBUILD_ZIPFILE=%FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_FILE_ID%%FBBUILD_FILENAME_SUFFIX%.zip + set SKIP_FILES=%SKIP_FILES% -x!*.pdb ) -@%SEVENZIP%\7z.exe a -r -tzip -mx9 %FBBUILD_ZIPFILE% %FBBUILD_ZIP_PACK_ROOT%\*.* -@echo End of ZIP_PACK -@echo. +if "%FB2_EXAMPLES%" == "0" set SKIP_FILES=%SKIP_FILES% -xr-!examples + +if exist %FBBUILD_ZIPFILE% ( + @del %FBBUILD_ZIPFILE% +) + +%SEVENZIP%\7z.exe a -r -tzip -mx9 %SKIP_FILES% %FBBUILD_ZIPFILE% %FB_OUTPUT_DIR%\*.* + +endlocal + +::End of ZIP_PACK ::---------------- @goto :EOF @@ -583,12 +492,23 @@ if "%FBBUILD_SHIP_PDB%" == "ship_pdb" ( ::While building and testing this feature might be annoying, so we don't do it. ::========================================================== setlocal -set TIMESTRING=0%PRODUCT_VER_STRING:~0,1%:0%PRODUCT_VER_STRING:~2,1%:0%PRODUCT_VER_STRING:~4,1% -@if /I "%BUILDTYPE%"=="release" ( - (@echo Touching release build files with %TIMESTRING% timestamp) & (touch -s -D -t%TIMESTRING% %FB_OUTPUT_DIR%\*.*) - (if %FBBUILD_ZIP_PACK% EQU 1 (@echo Touching release build files with %TIMESTRING% timestamp) & (touch -s -D -t%TIMESTRING% %FB_ROOT_PATH%\zip_pack\*.*) ) + +if /I not "%FBBUILD_BUILDTYPE%"=="release" goto :EOF +if not defined TOUCH_COMMAND echo POSIX touch utility not found && exit /b 1 + +set TIMESTRING=0%FB_MAJOR_VER%:0%FB_MINOR_VER%:0%FB_REV_NO% + +:: Perhaps here we should touch directories as well +:: Here and there XXX_COMMAND is "call"-ed in case if it is a batch file + +@echo Touching release build files with %TIMESTRING% timestamp + +@for /R %FB_OUTPUT_DIR% %%F in ( * ) do ( + call %TOUCH_COMMAND% -c -d %TIMESTRING% %%F || exit /b 1 ) + endlocal + ::End of TOUCH_ALL ::---------------- @goto :EOF @@ -602,14 +522,11 @@ endlocal :: eg set INNO5_SETUP_PATH="C:\Program Files\Inno Setup 5" :: ::================================================= -if %FBBUILD_ISX_PACK% NEQ 1 goto :EOF -@echo Now let's compile the InnoSetup scripts @echo. -%INNO5_SETUP_PATH%\iscc %FB_ROOT_PATH%\builds\install\arch-specific\win32\FirebirdInstall_%FBBUILD_FILE_ID%.iss +call %ISCC_COMMAND% %FB_ROOT_PATH%\builds\install\arch-specific\win32\FirebirdInstall.iss @echo. -@echo End of ISX_PACK -@echo. +::End of ISX_PACK ::--------------- @goto :EOF @@ -618,15 +535,25 @@ if %FBBUILD_ISX_PACK% NEQ 1 goto :EOF ::========= :: Generate the md5sum checksum file ::================================== -if NOT DEFINED GNU_TOOLCHAIN ( - call :WARNING GNU_TOOLCHAIN variable not defined. Cannot generate md5 sums. +if not defined MD5_COMMAND ( + call :WARNING md5sum utility not found. Cannot generate md5 sums. @goto :EOF ) -@echo Generating md5sums for Firebird-%FBBUILD_PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER% +@echo Generating md5sums for Firebird-%PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER% -%GNU_TOOLCHAIN%\md5sum.exe %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_PRODUCT_VER_STRING%?%FBBUILD_PACKAGE_NUMBER%*.* > %FBBUILD_INSTALL_IMAGES%\Firebird-%FBBUILD_PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER%.md5sum +:: write sums into temporary file to avoid including it into the process +pushd %FBBUILD_INSTALL_IMAGES% +call %MD5_COMMAND% Firebird-%PRODUCT_VER_STRING%?%FBBUILD_PACKAGE_NUMBER%*.* >md5sum.tmp -::--------------- +:: then rename it to the proper name +if not errorlevel 1 ( + del Firebird-%PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER%.md5sum >nul 2>nul + ren md5sum.tmp Firebird-%PRODUCT_VER_STRING%-%FBBUILD_PACKAGE_NUMBER%.md5sum +) +popd + +::End of DO_MD5SUMS +::----------------- @goto :EOF @@ -654,7 +581,7 @@ if NOT DEFINED GNU_TOOLCHAIN ( @echo. @echo HELP This help screen. @echo. -@echo In addition, the following environment variables are checked: +@echo In addition, the following environment variables are checked by ISS script: @echo. @echo FB2_ISS_DEBUG=1 - Prepare an InnoSetup script that is @echo easier to debug @@ -729,7 +656,6 @@ popd @if errorlevel 1 (goto :END) @if not defined FB2_ISS_DEBUG (set FB2_ISS_DEBUG=0) -@if not defined FB2_EXAMPLES (set FB2_EXAMPLES=1) @echo. @echo Reading command-line parameters... @@ -742,7 +668,7 @@ popd @echo. @echo Setting version number... -@(@call :SED_MAGIC ) || (@echo Error calling SED_MAGIC && @goto :END) +@(@call :SET_VERSION ) || (@echo Error calling SET_VERSION && @goto :END) @echo. @echo Copying additional files needed for installation, documentation etc. @@ -776,13 +702,6 @@ if defined WIX ( @(@call :SET_CRLF ) || (@echo Error calling SET_CRLF && @goto :EOF) @echo. - -if %FBBUILD_ZIP_PACK% EQU 1 ( -@echo Generating image of zipped install -@(@call :GEN_ZIP ) || (@echo Error calling GEN_ZIP && @goto :END) -@echo. -) - ::@echo Creating .local files for libraries ::@(@call :TOUCH_LOCAL ) || (@echo Error calling TOUCH_LOCAL & @goto :END) ::@echo. @@ -797,6 +716,7 @@ if %FBBUILD_ZIP_PACK% EQU 1 ( ) if %FBBUILD_ISX_PACK% EQU 1 ( +@echo Now let's compile the InnoSetup scripts @(@call :ISX_PACK ) || (@echo Error calling ISX_PACK && @goto :END) @echo. ) @@ -815,7 +735,7 @@ if %FBBUILD_ISX_PACK% EQU 1 ( :END -popd + exit /b diff --git a/builds/install/arch-specific/win32/FirebirdInstall.iss b/builds/install/arch-specific/win32/FirebirdInstall.iss index 57840935ee..49c7557776 100644 --- a/builds/install/arch-specific/win32/FirebirdInstall.iss +++ b/builds/install/arch-specific/win32/FirebirdInstall.iss @@ -49,30 +49,46 @@ #define FirebirdURL MyAppURL #define UninstallBinary "{app}\firebird.exe" +#define Root GetEnv("FB_ROOT_PATH") +#if Root == "" +;We are not run from batch file, let's set some sane defaults +#define Root = "..\..\..\.." +;Assume iss debug as well +#define iss_debug +#else + +#endif + +#if GetEnv("FB2_ISS_DEBUG") == "1" +#define iss_debug +#endif + +#if GetEnv("FBBUILD_SHIP_PDB") == "ship_pdb" +#define ship_pdb +#endif + +;Get version information from build_no.h +#include Root + "\gen\jrd\build_no.h" + ;Hard code some defaults to aid debugging and running script standalone. ;In practice, these values are set in the environment and we use the env vars. -#define MajorVer "4" -#define MinorVer "0" -#define PointRelease "0" -#define BuildNumber "0" +#define PackageNumber GetEnv("FBBUILD_PACKAGE_NUMBER") +#if PackageNumber == "" #define PackageNumber "0" -#define FilenameSuffix "" - +#endif +#define FilenameSuffix GetEnv("FBBUILD_FILENAME_SUFFIX") +#if FilenameSuffix != "" && pos('_',FilenameSuffix) == 0 +#define FilenameSuffix "_" + FilenameSuffix +#endif ;-------Start of Innosetup script debug flags section -; if iss_release is undefined then iss_debug is set +; if iss_debug is undefined then iss_release is set ; Setting iss_release implies that the defines for files, ; examples and compression are set. If debug is set then this ; section controls the settings of files, examples ; and compression. -; A dynamically generated sed script sets the appropriate define -; See BuildExecutableInstall.bat for more details. - - -;#define iss_debug - #ifndef iss_debug #define iss_release #endif @@ -80,10 +96,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;; #ifdef iss_release #define files +#if GetEnv("FB2_EXAMPLES") != "0" #define examples +#endif #define compression -#else -#define iss_debug +#define i18n #endif ;-------------------- @@ -107,72 +124,8 @@ ;-------end of Innosetup script debug flags section - ;-------Start of Innosetup script - -;---- These three defines need a bit of tidying up in the near future, -; but for now they must stay, as the BuildExecutableInstall.bat -; uses them. -#define release -#define no_pdb -#define i18n - - -;------If necessary we can turn off i18n by uncommenting this undefine -;------In general this is a good idea for alpha and beta releases. -#undef i18n - -;----- If we are debugging the script (and not executed from command prompt) -;----- there is no guarantee that the environment variable exists. However an -;----- expression such as #define FB_MAJOR_VER GetEnv("FB_MAJOR_VER") will -;----- 'define' the macro anyway so we need to test for a valid env var before -;----- we define our macro. -#if Len(GetEnv("FB_MAJOR_VER")) > 0 -#define FB_MAJOR_VER GetEnv("FB_MAJOR_VER") -#endif -#ifdef FB_MAJOR_VER -#define MajorVer FB_MAJOR_VER -#endif - -#if Len(GetEnv("FB_MINOR_VER")) > 0 -#define FB_MINOR_VER GetEnv("FB_MINOR_VER") -#endif -#ifdef FB_MINOR_VER -#define MinorVer FB_MINOR_VER -#endif - -#if Len(GetEnv("FB_REV_NO")) > 0 -#define FB_REV_NO GetEnv("FB_REV_NO") -#endif -#ifdef FB_REV_NO -#define PointRelease FB_REV_NO -#endif - -#if Len(GetEnv("FB_BUILD_NO")) > 0 -#define FB_BUILD_NO GetEnv("FB_BUILD_NO") -#endif -#ifdef FB_BUILD_NO -#define BuildNumber FB_BUILD_NO -#endif - -#if Len(GetEnv("FBBUILD_PACKAGE_NUMBER")) > 0 -#define FBBUILD_PACKAGE_NUMBER GetEnv("FBBUILD_PACKAGE_NUMBER") -#endif -#ifdef FBBUILD_PACKAGE_NUMBER -#define PackageNumber FBBUILD_PACKAGE_NUMBER -#endif - -#if Len(GetEnv("FBBUILD_FILENAME_SUFFIX")) > 0 -#define FBBUILD_FILENAME_SUFFIX GetEnv("FBBUILD_FILENAME_SUFFIX") -#endif -#ifdef FBBUILD_FILENAME_SUFFIX -#define FilenameSuffix FBBUILD_FILENAME_SUFFIX -#if pos('_',FilenameSuffix) == 0 -#define FilenameSuffix "_" + FilenameSuffix -#endif -#endif - #if Len(GetEnv("MSVC_VERSION")) > 0 #define msvc_version GetEnv("MSVC_VERSION") #else @@ -212,10 +165,10 @@ #define msvcr_filename = "vcruntime" #endif -#if BuildNumber == "0" -#define MyAppVerString MajorVer + "." + MinorVer + "." + PointRelease +#if FB_BUILD_NO == "0" +#define MyAppVerString FB_MAJOR_VER + "." + FB_MINOR_VER + "." + FB_REV_NO #else -#define MyAppVerString MajorVer + "." + MinorVer + "." + PointRelease + "." + BuildNumber +#define MyAppVerString FB_MAJOR_VER + "." + FB_MINOR_VER + "." + FB_REV_NO + "." + FB_BUILD_NO #endif #define MyAppVerName MyAppName + " " + MyAppVerString @@ -224,11 +177,16 @@ #define PlatformTarget GetEnv("FB_TARGET_PLATFORM") #endif #if PlatformTarget == "" +;Assume native platform +#if IsWin64 +#define PlatformTarget "x64" +#else #define PlatformTarget "win32" #endif +#endif +#if FB_BUILD_TYPE == "T" ;If we are still under development we can ignore some missing files. -#if GetEnv("FBBUILD_PROD_STATUS") == "DEV" #define SkipFileIfDevStatus " skipifsourcedoesntexist " #else #define SkipFileIfDevStatus " " @@ -240,21 +198,12 @@ #define WOW64Dir="output_win32" #endif -;BaseVer should be used for all MajorVer.MinorVer installs. -;This allows us to upgrade silently from MajorVer.MinorVer.m to MajorVer.MinorVer.n -#define BaseVer MajorVer + "_" + MinorVer -#define AppVer MajorVer + "_" + MinorVer -#define GroupnameVer MajorVer + "." + MinorVer - -;These variables are set in BuildExecutableInstall -#define FB15_cur_ver GetEnv("FBBUILD_FB15_CUR_VER") -#define FB20_cur_ver GetEnv("FBBUILD_FB20_CUR_VER") -#define FB21_cur_ver GetEnv("FBBUILD_FB21_CUR_VER") -#define FB25_cur_ver GetEnv("FBBUILD_FB25_CUR_VER") -#define FB30_cur_ver GetEnv("FBBUILD_FB30_CUR_VER") -#define FB40_cur_ver GetEnv("FBBUILD_FB40_CUR_VER") -#define FB_cur_ver FB40_cur_ver -#define FB_last_ver FB30_cur_ver +;BaseVer should be used for all FB_MAJOR_VER.FB_MINOR_VER installs. +;This allows us to upgrade silently from FB_MAJOR_VER.FB_MINOR_VER.m to FB_MAJOR_VER.FB_MINOR_VER.n +#define BaseVer FB_MAJOR_VER + "_" + FB_MINOR_VER +#define AppVer FB_MAJOR_VER + "_" + FB_MINOR_VER +#define GroupnameVer FB_MAJOR_VER + "." + FB_MINOR_VER +#define FB_cur_ver FB_MAJOR_VER + "." + FB_MINOR_VER + "." + FB_REV_NO ; We can save space by shipping a pdb package that just includes ; the pdb files. It would then upgrade an existing installation, @@ -276,7 +225,7 @@ #else #define pdb_str="" #endif -#ifdef debug +#if GetEnv("FBBUILD_BUILDTYPE") == "debug" #define debug_str="_debug" #else #define debug_str="" @@ -300,7 +249,7 @@ AppUpdatesURL={#MyAppURL} AppVersion={#MyAppVerString} VersionInfoVersion={#MyAppVerString} -SourceDir=..\..\..\..\ +SourceDir={#Root} OutputBaseFilename={#MyAppName}-{#MyAppVerString}_{#PackageNumber}_{#PlatformTarget}{#debug_str}{#pdb_str}{#FilenameSuffix} ;OutputManifestFile={#MyAppName}-{#MyAppVerString}_{#PackageNumber}_{#PlatformTarget}{#debug_str}{#pdb_str}{#FilenameSuffix}_Setup-Manifest.txt OutputDir=builds\install_images @@ -342,7 +291,7 @@ SetupLogging=yes #endif [Languages] -Name: en; MessagesFile: compiler:Default.isl; InfoBeforeFile: {#GenDir}\installation_readme.txt; InfoAfterFile: {#GenDir}\readme.txt; +Name: en; MessagesFile: compiler:Default.isl; InfoBeforeFile: {#GenDir}\installation_readme.txt; InfoAfterFile: {#GenDir}\Readme.txt; #ifdef i18n Name: ba; MessagesFile: compiler:Languages\Bosnian.isl; InfoBeforeFile: {#GenDir}\ba\Instalacija_ProcitajMe.txt; InfoAfterFile: {#GenDir}\ba\ProcitajMe.txt; Name: cz; MessagesFile: compiler:Languages\Czech.isl; InfoBeforeFile: {#GenDir}\cz\instalace_ctime.txt; InfoAfterFile: {#GenDir}\cz\ctime.txt; @@ -389,21 +338,6 @@ Name: ru; MessagesFile: compiler:Languages\Russian.isl; InfoBeforeFile: {#GenDir ;#include "si\custom_messages_si.inc" #endif -#ifdef iss_debug -; *** Note - this comment section needs revision or deletion. -; It is only applicable to the ansi installer, which is no longer -; supported for Firebird 3 -; By default, the languages available at runtime depend on the user's -; code page. A user with the Western European code page set will not -; even see that we support installation with the czech language -; for example. -; It can be useful when debugging to force the display of all available -; languages by setting LanguageCodePage to 0. Of course, if the langauge -; is not supported by the user's current code page it will be unusable. -[LangOptions] -LanguageCodePage=0 -#endif - [Types] Name: ServerInstall; Description: {cm:ServerInstall} Name: DeveloperInstall; Description: {cm:DeveloperInstall} @@ -478,7 +412,7 @@ Name: {group}\Firebird Server; Filename: {app}\firebird.exe; Parameters: {code:S Name: {group}\Firebird Guardian; Filename: {app}\fbguard.exe; Parameters: {code:StartAppParams}; Flags: runminimized; MinVersion: 4.0,4.0; Check: InstallGuardianIcon; IconIndex: 1; Components: ServerComponent; Comment: Run Firebird Server (with guardian); Name: {group}\Firebird ISQL Tool; Filename: {app}\isql.exe; Parameters: -z; WorkingDir: {app}; MinVersion: 4.0,4.0; Comment: {cm:RunISQL} Name: {group}\Firebird {#FB_cur_ver} Release Notes; Filename: {app}\doc\Firebird_v{#FB_cur_ver}.ReleaseNotes.pdf; MinVersion: 4.0,4.0; Comment: {#MyAppName} {cm:ReleaseNotes} -;Name: {group}\Firebird {#GroupnameVer} Quick Start Guide; Filename: {app}\doc\Firebird-{#MajorVer}-QuickStart.pdf; MinVersion: 4.0,4.0; Comment: {#MyAppName} {#FB_cur_ver} +;Name: {group}\Firebird {#GroupnameVer} Quick Start Guide; Filename: {app}\doc\Firebird-{#FB_MAJOR_VER}-QuickStart.pdf; MinVersion: 4.0,4.0; Comment: {#MyAppName} {#FB_cur_ver} Name: "{group}\After Installation"; Filename: "{app}\doc\After_Installation.url"; Comment: "New User? Here's a quick guide to what you should do next." Name: "{group}\Firebird Web-site"; Filename: "{app}\doc\firebirdsql.org.url" ;Always install the original english version @@ -493,7 +427,7 @@ Name: {group}\{cm:Uninstall,{#FB_cur_ver}}; Filename: {uninstallexe}; Comment: U #ifdef files Source: {#LicensesDir}\IPLicense.txt; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion; Source: {#LicensesDir}\IDPLicense.txt; DestDir: {app}; Components: ClientComponent; Flags: sharedfile ignoreversion -Source: {#ScriptsDir}\After_Installation.url; DestDir: {app}\doc; Components: ServerComponent DevAdminComponent; Flags: sharedfile ignoreversion +Source: {#file "After_Installation.url"}; DestDir: {app}\doc; DestName: "After_Installation.url"; Components: ServerComponent DevAdminComponent; Flags: sharedfile ignoreversion Source: {#ScriptsDir}\firebirdsql.org.url; DestDir: {app}\doc; Components: ServerComponent DevAdminComponent; Flags: sharedfile ignoreversion ;Always install the original english version Source: {#GenDir}\readme.txt; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion; @@ -543,8 +477,8 @@ Source: {#FilesDir}\fbsvcmgr.exe; DestDir: {app}; Components: DevAdminComponent; Source: {#FilesDir}\fbtracemgr.exe; DestDir: {app}; Components: DevAdminComponent; Flags: ignoreversion Source: {#FilesDir}\fbclient.dll; DestDir: {app}; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder #if PlatformTarget == "x64" -Source: {#WOW64Dir}\fbclient.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder -Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion +Source: {#WOW64Dir}\fbclient.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: overwritereadonly sharedfile promptifolder {#SkipFileIfDevStatus} +Source: {#WOW64Dir}\instclient.exe; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile ignoreversion {#SkipFileIfDevStatus} #endif Source: {#FilesDir}\icuuc??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion Source: {#FilesDir}\icuin??.dll; DestDir: {app}; Components: ServerComponent; Flags: sharedfile ignoreversion @@ -563,8 +497,8 @@ Source: {#FilesDir}\{#msvcr_filename}{#msvc_runtime_major_version}{#msvc_runtime Source: {#FilesDir}\msvcp{#msvc_runtime_major_version}{#msvc_runtime_minor_version_0}.dll; DestDir: {app}; Components: ClientComponent; Flags: sharedfile; #if PlatformTarget == "x64" ;If we are installing on x64 we need some 32-bit libraries for compatibility with 32-bit applications -Source: {#WOW64Dir}\{#msvcr_filename}{#msvc_runtime_major_version}{#msvc_runtime_minor_version_0}.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile; -Source: {#WOW64Dir}\msvcp{#msvc_runtime_major_version}{#msvc_runtime_minor_version_0}.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile; +Source: {#WOW64Dir}\{#msvcr_filename}{#msvc_runtime_major_version}{#msvc_runtime_minor_version_0}.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile {#SkipFileIfDevStatus}; +Source: {#WOW64Dir}\msvcp{#msvc_runtime_major_version}{#msvc_runtime_minor_version_0}.dll; DestDir: {app}\WOW64; Components: ClientComponent; Flags: sharedfile {#SkipFileIfDevStatus}; #endif #endif /* #if Int(msvc_runtime_major_version,14) >= 10 */ @@ -572,10 +506,10 @@ Source: {#WOW64Dir}\msvcp{#msvc_runtime_major_version}{#msvc_runtime_minor_versi #if PlatformTarget == "x64" ;MinVersion 0,5.0 means no version of Win9x and at least Win2k if NT O/S ;In addition, O/S must have Windows Installer 3.0. -Source: {#FilesDir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_x64.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; -Source: {#WOW64Dir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_Win32.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; +Source: {#FilesDir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_x64.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; Flags: {#SkipFileIfDevStatus} +Source: {#WOW64Dir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_Win32.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; Flags: {#SkipFileIfDevStatus} #else -Source: {#FilesDir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_Win32.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; +Source: {#FilesDir}\system32\vccrt{#msvc_runtime_major_version}{#msvc_runtime_minor_version_1}_Win32.msi; DestDir: {tmp}; Check: HasWI30; MinVersion: 0,5.0; Components: ClientComponent; Flags: {#SkipFileIfDevStatus} #endif #endif @@ -592,7 +526,7 @@ Source: {#FilesDir}\intl\fbintl.dll; DestDir: {app}\intl; Components: ServerComp Source: {#FilesDir}\intl\fbintl.conf; DestDir: {app}\intl; Components: ServerComponent; Flags: onlyifdoesntexist Source: {#FilesDir}\lib\*.*; DestDir: {app}\lib; Components: DevAdminComponent; Flags: ignoreversion; #if PlatformTarget == "x64" -Source: {#WOW64Dir}\lib\*.lib; DestDir: {app}\WOW64\lib; Components: DevAdminComponent; Flags: ignoreversion +Source: {#WOW64Dir}\lib\*.lib; DestDir: {app}\WOW64\lib; Components: DevAdminComponent; Flags: ignoreversion {#SkipFileIfDevStatus} #endif ;deprecated in FB4.0 @@ -832,7 +766,7 @@ begin InstallRootDir := Default; // but the user has changed the default if (( InstallRootDir = '') and - ( FirebirdVer[0] = {#MajorVer} ) and ( FirebirdVer[1] = {#MinorVer} ) ) then // Firebird 2.n is installed + ( FirebirdVer[0] = {#FB_MAJOR_VER} ) and ( FirebirdVer[1] = {#FB_MINOR_VER} ) ) then // Firebird 2.n is installed InstallRootDir := FirebirdRootDir; // but the user has changed the default // if we haven't found anything then try the FIREBIRD env var diff --git a/builds/install/arch-specific/win32/Readme_DEV.txt b/builds/install/arch-specific/win32/Readme_DEV.txt index f245899119..5b2568ca1a 100644 --- a/builds/install/arch-specific/win32/Readme_DEV.txt +++ b/builds/install/arch-specific/win32/Readme_DEV.txt @@ -28,6 +28,8 @@ considered ready for use in production. o Please make sure you read the installation readme and the release notes. + + Reporting Bugs ============== diff --git a/builds/install/arch-specific/win32/i18n_readme.txt b/builds/install/arch-specific/win32/i18n_readme.txt index 541e9460c0..d4f4be669f 100644 --- a/builds/install/arch-specific/win32/i18n_readme.txt +++ b/builds/install/arch-specific/win32/i18n_readme.txt @@ -9,7 +9,7 @@ documentatation i18n should be available separately. I18n is a good thing, but bloating the installer with large amounts of translated documentation is not desirable. -The current version of InnoSetup used by Firebird $MAJOR.$MINOR - 5.5.8 - provides +The current version of InnoSetup used by Firebird - 5.5.8 - provides generic support for the following languages: BrazilianPortuguese, Catalan, Corsican, Czech, Danish, Dutch, Finnish, French, diff --git a/builds/install/misc/firebird.conf.in b/builds/install/misc/firebird.conf.in index 5830d25a9e..f627cd464e 100644 --- a/builds/install/misc/firebird.conf.in +++ b/builds/install/misc/firebird.conf.in @@ -180,7 +180,7 @@ # the same restrictions as in previous FB versions. To specify access # to specific trees, enum all required paths (for Windows this may be # something like 'C:\ExternalFunctions', for unix - '/db/udf;/mnt/udf'). -@UDF_COMMENT@ +# # NOTE: THE EXTERNAL FUNCTION ENGINE FEATURE COULD BE USED TO COMPROMISE # THE SERVER/HOST AS WELL AS DATABASE SECURITY!! # diff --git a/builds/win32/make_all.bat b/builds/win32/make_all.bat index d1f6ec1b7f..a7e2cbe8d2 100644 --- a/builds/win32/make_all.bat +++ b/builds/win32/make_all.bat @@ -64,8 +64,7 @@ for %%v in (gpre_boot build_msg codes) do ( :: Firebird.conf, etc @copy %FB_GEN_DIR%\firebird.msg %FB_OUTPUT_DIR% > nul -:: The line @UDF_COMMENT@ should be deleted from the target file. -findstr /V "@UDF_COMMENT@" %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in > %FB_OUTPUT_DIR%\firebird.conf +@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in %FB_OUTPUT_DIR%\firebird.conf @copy %FB_ROOT_PATH%\builds\install\misc\databases.conf.in %FB_OUTPUT_DIR%\databases.conf >nul @copy %FB_ROOT_PATH%\builds\install\misc\fbintl.conf %FB_OUTPUT_DIR%\intl >nul @copy %FB_ROOT_PATH%\builds\install\misc\plugins.conf %FB_OUTPUT_DIR% >nul diff --git a/builds/win32/make_boot.bat b/builds/win32/make_boot.bat index 5683e08830..dd00e6e3bd 100644 --- a/builds/win32/make_boot.bat +++ b/builds/win32/make_boot.bat @@ -75,7 +75,7 @@ if "%ERRLEV%"=="1" goto :END call :isql if "%ERRLEV%"=="1" goto :END -@findstr /V "@UDF_COMMENT@" %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in > %FB_BIN_DIR%\firebird.conf +@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in %FB_BIN_DIR%\firebird.conf :: Copy ICU and zlib both to Debug and Release configurations diff --git a/builds/win32/make_examples.bat b/builds/win32/make_examples.bat index e3db17867f..60df8c9936 100644 --- a/builds/win32/make_examples.bat +++ b/builds/win32/make_examples.bat @@ -1,5 +1,4 @@ -::@echo off - +@echo off :: Set env vars @call setenvvar.bat @@ -38,8 +37,9 @@ if errorlevel 1 ( @call :MOVE2 @goto :EOF -::=========== + :BUILD_EMPBUILD +::=========== @echo. @echo Building empbuild.fdb @copy /y %FB_ROOT_PATH%\examples\empbuild\*.sql %FB_GEN_DIR%\examples\ > nul @@ -47,7 +47,7 @@ if errorlevel 1 ( @echo. :: Here we must use cd because isql does not have an option to set a base directory -@cd "%FB_LONG_ROOT_PATH%\gen\examples" +@pushd "%FB_LONG_ROOT_PATH%\gen\examples" @echo Creating empbuild.fdb... @echo. @del empbuild.fdb 2> nul @@ -62,7 +62,8 @@ if defined FB2_INTLEMP ( @%FB_BIN_DIR%\isql -i intlbld.sql ) -@cd "%FB_LONG_ROOT_PATH%\builds\win32" +@popd + @echo. @echo path = %FB_GEN_DB_DIR%\examples @echo Preprocessing empbuild.e... @@ -75,17 +76,18 @@ if defined FB2_INTLEMP ( @%FB_BIN_DIR%\gpre.exe -r -m -n -z %FB_ROOT_PATH%\examples\empbuild\intlbld.e %FB_GEN_DIR%\examples\intlbld.c -b %FB_GEN_DB_DIR%/examples/ ) +::End of BUILD_EMPBUILD +::--------------------- @goto :EOF -::=========== :MOVE +::=========== @echo. @rmdir /q /s %FB_OUTPUT_DIR%\examples 2>nul @mkdir %FB_OUTPUT_DIR%\examples @mkdir %FB_OUTPUT_DIR%\examples\api @mkdir %FB_OUTPUT_DIR%\examples\dbcrypt -@mkdir %FB_OUTPUT_DIR%\examples\build_unix @mkdir %FB_OUTPUT_DIR%\examples\build_win32 @mkdir %FB_OUTPUT_DIR%\examples\empbuild @mkdir %FB_OUTPUT_DIR%\examples\include @@ -97,23 +99,20 @@ if defined FB2_INTLEMP ( @mkdir %FB_OUTPUT_DIR%\plugins\udr 2>nul @echo Moving files to output directory -@copy %FB_ROOT_PATH%\examples\* %FB_OUTPUT_DIR%\examples > nul -@ren %FB_OUTPUT_DIR%\examples\readme readme.txt > nul -@copy %FB_ROOT_PATH%\examples\api\* %FB_OUTPUT_DIR%\examples\api > nul -@copy %FB_ROOT_PATH%\examples\dbcrypt\* %FB_OUTPUT_DIR%\examples\dbcrypt > nul -@copy %FB_ROOT_PATH%\examples\build_unix\* %FB_OUTPUT_DIR%\examples\build_unix > nul -@copy %FB_ROOT_PATH%\examples\build_win32\* %FB_OUTPUT_DIR%\examples\build_win32 > nul +copy %FB_ROOT_PATH%\examples\* %FB_OUTPUT_DIR%\examples > nul +ren %FB_OUTPUT_DIR%\examples\readme readme.txt > nul +copy %FB_ROOT_PATH%\examples\api\* %FB_OUTPUT_DIR%\examples\api > nul +copy %FB_ROOT_PATH%\examples\dbcrypt\* %FB_OUTPUT_DIR%\examples\dbcrypt > nul +copy %FB_ROOT_PATH%\examples\build_win32\* %FB_OUTPUT_DIR%\examples\build_win32 > nul :: @copy %FB_ROOT_PATH%\examples\empbuild\* %FB_OUTPUT_DIR%\examples\empbuild > nul -@copy %FB_ROOT_PATH%\examples\empbuild\employe2.sql %FB_OUTPUT_DIR%\examples\empbuild > nul -@copy %FB_ROOT_PATH%\examples\include\* %FB_OUTPUT_DIR%\examples\include > nul -@copy %FB_ROOT_PATH%\examples\interfaces\* %FB_OUTPUT_DIR%\examples\interfaces > nul -@copy %FB_ROOT_PATH%\examples\package\* %FB_OUTPUT_DIR%\examples\package > nul -@copy %FB_ROOT_PATH%\examples\stat\* %FB_OUTPUT_DIR%\examples\stat > nul -@copy %FB_ROOT_PATH%\examples\udf\* %FB_OUTPUT_DIR%\examples\udf > nul -@copy %FB_ROOT_PATH%\examples\udr\* %FB_OUTPUT_DIR%\examples\udr > nul -@copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\plugins\udr\*.dll %FB_OUTPUT_DIR%\plugins\udr >nul -@copy %FB_ROOT_PATH%\src\extlib\ib_udf* %FB_OUTPUT_DIR%\examples\udf > nul -@copy %FB_ROOT_PATH%\src\extlib\fbudf\* %FB_OUTPUT_DIR%\examples\udf > nul +copy %FB_ROOT_PATH%\examples\empbuild\employe2.sql %FB_OUTPUT_DIR%\examples\empbuild > nul +copy %FB_ROOT_PATH%\examples\include\* %FB_OUTPUT_DIR%\examples\include > nul +copy %FB_ROOT_PATH%\examples\interfaces\* %FB_OUTPUT_DIR%\examples\interfaces > nul +copy %FB_ROOT_PATH%\examples\package\* %FB_OUTPUT_DIR%\examples\package > nul +copy %FB_ROOT_PATH%\examples\stat\* %FB_OUTPUT_DIR%\examples\stat > nul +copy %FB_ROOT_PATH%\examples\udf\* %FB_OUTPUT_DIR%\examples\udf > nul +copy %FB_ROOT_PATH%\examples\udr\* %FB_OUTPUT_DIR%\examples\udr > nul +copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\plugins\udr\*.dll %FB_OUTPUT_DIR%\plugins\udr >nul ::@copy %FB_GEN_DIR%\examples\empbuild.c %FB_OUTPUT_DIR%\examples\empbuild\ > nul ::@copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\examples\empbuild.exe %FB_GEN_DIR%\examples\empbuild.exe > nul @@ -124,37 +123,50 @@ if defined FB2_INTLEMP ( ::@copy %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\examples\intlbuild.exe %FB_GEN_DIR%\examples\intlbuild.exe > nul ::) ::) + +::End of MOVE +::----------- @goto :EOF +:BUILD_EMPLOYEE ::=========== :: only to test if it works -:BUILD_EMPLOYEE + @echo. @echo Building employee.fdb -:: Here we must use cd because isql does not have an option to set a base directory -:: and empbuild.exe uses isql -@set FB_SAVE_PATH=%PATH% -@set PATH=%FB_BIN_DIR%;%PATH% + +:: Do no mess with global variables +setlocal + :: This allows us to use the new engine in embedded mode to build :: the employee database. @set FIREBIRD=%FB_BIN_DIR% +@set PATH=%FB_BIN_DIR%;%PATH% -@cd "%FB_LONG_ROOT_PATH%\gen\examples" -@del %FB_GEN_DIR%\examples\employee.fdb 2>nul -@%FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\empbuild\empbuild.exe %FB_GEN_DB_DIR%/examples/employee.fdb -if errorlevel 44 (call :ERROR empbuild.exe failed - see empbuild_%FB_TARGET_PLATFORM%.log for details & goto :EOF) +:: Here we must use cd because isql does not have an option to set a base directory +:: and empbuild.exe uses isql +:: BEWARE: It will run without error if you have FB client from previous version +:: installed in System32 and server run but created database will have +:: wrong ODS. +@pushd "%FB_GEN_DIR%\examples" +if exist employee.fdb del employee.fdb + +%FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\empbuild\empbuild.exe %FB_GEN_DB_DIR%/examples/employee.fdb +if errorlevel 44 (call :ERROR empbuild.exe failed - see empbuild_%FB_TARGET_PLATFORM%.log for details ) @if defined FB2_INTLEMP ( @echo Building intlemp.fdb @del %FB_GEN_DIR%\examples\intlemp.fdb 2>nul @del isql.tmp 2>nul - @echo s;intlemp.fdb;%SERVER_NAME%:%FB_GEN_DIR%\examples\intlemp.fdb;g > isql.tmp + @echo s;intlemp.fdb;%FB_GEN_DIR%\examples\intlemp.fdb;g > isql.tmp @%FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\intlbuild\intlbuild.exe %FB_GEN_DB_DIR%/examples/intlemp.fdb ) -@set FIREBIRD= -@set PATH=%FB_SAVE_PATH% -@cd "%FB_LONG_ROOT_PATH%\builds\win32" +@popd +endlocal + +::End of BUILD_EMPLOYEE +::--------------------- @goto :EOF ::============== @@ -182,8 +194,8 @@ if defined FB2_INTLEMP ( @echo Error - %* @echo. set ERRLEV=1 -cancel_script > nul 2>&1 + +exit /b 1 + ::End of ERROR ::------------ -@goto :EOF - diff --git a/builds/win32/setenvvar.bat b/builds/win32/setenvvar.bat index ce2bbfec59..724f8bfc26 100644 --- a/builds/win32/setenvvar.bat +++ b/builds/win32/setenvvar.bat @@ -4,11 +4,6 @@ :: FB_DB_PATH unix format path of the main directory :: (This is used by gpre and preprocess.bat) :: VS_VER VisualStudio version (msvc10|msvc12|msvc14) -:: SERVER_NAME server needed to connect to firebird (could include port) -:: Example : localhost/3051 -:: (Note - SERVER_NAME is almost deprecated - it is only used by -:: make_examples.bat -:: @echo off @@ -48,8 +43,6 @@ set VS_VER=msvc%MSVC_VERSION% ::================= :SET_DB_DIR -@SET SERVER_NAME=localhost - @cd ..\.. @for /f "delims=" %%a in ('@cd') do (set FB_LONG_ROOT_PATH=%%a) @for /f "delims=" %%a in ('@cd') do (set FB_ROOT_PATH=%%~sa) @@ -108,7 +101,6 @@ if defined VS_VER_EXPRESS ( @echo msvc_version=%MSVC_VERSION% @echo db_path=%FB_DB_PATH% @echo root_path=%FB_ROOT_PATH% -@echo server_name=%SERVER_NAME% @echo. @echo (End of %0) @echo. diff --git a/configure.ac b/configure.ac index ac5a445f82..8dead2da79 100644 --- a/configure.ac +++ b/configure.ac @@ -1371,9 +1371,6 @@ else fi AC_SUBST(POSTFIX_INCLUDE) -UDF_COMMENT="#" -AC_SUBST(UDF_COMMENT) - AC_CONFIG_FILES( gen/make.rules:${MAKE_SRC_DIR}/make.rules gen/make.defaults:${MAKE_SRC_DIR}/make.defaults diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dfedabe21b..b46b91ec12 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -909,7 +909,7 @@ add_custom_target(copy_files COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/security.fdb ${output_dir}/security4.fdb COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/help.fdb ${output_dir}/help/help.fdb # configs, text files - COMMAND sed "/@UDF_COMMENT@/d" < ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in > ${output_dir}/firebird.conf + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in ${output_dir}/firebird.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf.in ${output_dir}/databases.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/fbintl.conf ${output_dir}/intl/fbintl.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/plugins.conf ${output_dir}/plugins.conf From b9f4c652202eadefc2b5267d139545f5d6878043 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Wed, 15 Jan 2020 18:02:03 +0300 Subject: [PATCH 15/39] Added various ways to get infomation about wire crypt plugin name: variable in rdb$get_context(), field in mon$attachments and tag in Attachment::getInfo() --- doc/README.monitoring_tables | 1 + doc/sql.extensions/README.context_variables2 | 3 +++ doc/sql.extensions/README.isc_info_xxx | 14 +++++++++++++- src/include/firebird/impl/consts_pub.h | 11 +++++++++-- src/include/firebird/impl/inf_pub.h | 2 ++ src/include/gen/ids.h | 1 + src/isql/show.epp | 6 ++++++ src/jrd/Attachment.cpp | 1 + src/jrd/Attachment.h | 1 + src/jrd/Monitoring.cpp | 2 ++ src/jrd/SysFunction.cpp | 8 ++++++++ src/jrd/fields.h | 3 ++- src/jrd/inf.cpp | 13 +++++++++++++ src/jrd/jrd.cpp | 5 +++++ src/jrd/names.h | 1 + src/jrd/relations.h | 1 + src/remote/remote.h | 5 +++-- src/remote/server/server.cpp | 4 ++++ 18 files changed, 76 insertions(+), 6 deletions(-) diff --git a/doc/README.monitoring_tables b/doc/README.monitoring_tables index b6918f661d..ea5477651c 100644 --- a/doc/README.monitoring_tables +++ b/doc/README.monitoring_tables @@ -114,6 +114,7 @@ Monitoring tables - MON$STATEMENT_TIMEOUT (statement timeout) - MON$WIRE_COMPRESSED (wire compression enabled/disabled) - MON$WIRE_ENCRYPTED (wire encryption enabled/disabled) + - MON$WIRE_CRYPT_PLUGIN (name of wire encryption plugin) MON$TRANSACTIONS (started transactions) - MON$TRANSACTION_ID (transaction ID) diff --git a/doc/sql.extensions/README.context_variables2 b/doc/sql.extensions/README.context_variables2 index bac0d8ec92..1d6ef72ab9 100644 --- a/doc/sql.extensions/README.context_variables2 +++ b/doc/sql.extensions/README.context_variables2 @@ -64,6 +64,9 @@ Usage: WIRE_ENCRYPTED | Encryption status of current connection. | Value is the same as for compression status above. | + WIRE_CRYPT_PLUGIN | If connection is encrypted - returns name of current plugin, + | otherwise NULL. + | CLIENT_ADDRESS | The wire protocol address and port number of remote client | represented as string. Value is IP address concatenated with | port number using the '/' separator character. Value is diff --git a/doc/sql.extensions/README.isc_info_xxx b/doc/sql.extensions/README.isc_info_xxx index 7682f29597..e6aa9d0740 100644 --- a/doc/sql.extensions/README.isc_info_xxx +++ b/doc/sql.extensions/README.isc_info_xxx @@ -32,10 +32,22 @@ New items for isc_database_info See also CORE-2054. +4. Database encryption information: + fb_info_crypt_state - flags describing encryption state: + fb_info_crypt_encrypted - database is encrypted, + fb_info_crypt_process - encryption/decryption process is not complete; + fb_info_crypt_plugin - name of database crypt plugin; + fb_info_crypt_key - name of used database crypt key. + +5. Connection information: + fb_info_conn_flags - flags describing connection state: + isc_dpb_addr_flag_conn_compressed - compression is used for connection, + isc_dpb_addr_flag_conn_encrypted - connection is encrypted; + fb_info_wire_crypt - name of connection encryption plugin. New items for isc_transaction_info: - + 1. isc_info_tra_oldest_interesting : return number of oldest interesting transaction when current transaction started. For snapshot transactions this is also the diff --git a/src/include/firebird/impl/consts_pub.h b/src/include/firebird/impl/consts_pub.h index fc6f912f92..9ba14d70f9 100644 --- a/src/include/firebird/impl/consts_pub.h +++ b/src/include/firebird/impl/consts_pub.h @@ -153,8 +153,9 @@ ::= isc_dpb_addr_protocol | - isc_dpb_addr_endpoint - isc_dpb_addr_flags + isc_dpb_addr_endpoint | + isc_dpb_addr_flags | + isc_dpb_addr_crypt ::= "TCPv4" | @@ -163,6 +164,11 @@ "WNET" | .... + ::= + "Arc4" | + "ChaCha" | + .... + ::= | // such as "172.20.1.1" | // such as "2001:0:13FF:09FF::1" @@ -178,6 +184,7 @@ #define isc_dpb_addr_protocol 1 #define isc_dpb_addr_endpoint 2 #define isc_dpb_addr_flags 3 +#define isc_dpb_addr_crypt 4 /* possible addr flags */ #define isc_dpb_addr_flag_conn_compressed 0x01 diff --git a/src/include/firebird/impl/inf_pub.h b/src/include/firebird/impl/inf_pub.h index ea4d31eb9d..003ef9a68d 100644 --- a/src/include/firebird/impl/inf_pub.h +++ b/src/include/firebird/impl/inf_pub.h @@ -160,6 +160,8 @@ enum db_info_types fb_info_creation_timestamp_tz = 139, + fb_info_wire_crypt = 140, + isc_info_db_last_value /* Leave this LAST! */ }; diff --git a/src/include/gen/ids.h b/src/include/gen/ids.h index 9c3beca6b8..31cf55039c 100644 --- a/src/include/gen/ids.h +++ b/src/include/gen/ids.h @@ -524,6 +524,7 @@ const USHORT f_mon_att_stmt_timeout = 22; const USHORT f_mon_att_wire_compressed = 23; const USHORT f_mon_att_wire_encrypted = 24; + const USHORT f_mon_att_remote_crypt = 25; // Relation 35 (MON$TRANSACTIONS) diff --git a/src/isql/show.epp b/src/isql/show.epp index b36ebeb6ab..cdd23a5ea8 100644 --- a/src/isql/show.epp +++ b/src/isql/show.epp @@ -251,6 +251,7 @@ static const UCHAR db_items[] = isc_info_db_id, #endif fb_info_crypt_state, + fb_info_wire_crypt, isc_info_end }; @@ -554,6 +555,11 @@ bool SHOW_dbb_parameters(Firebird::IAttachment* db_handle, (SLONG) isqlGlob.major_ods, value_out, separator); break; + case fb_info_wire_crypt: + if (d) + sprintf (info, "Wire crypt plugin: %.*s%s", length, d, separator); + break; + #ifdef DEV_BUILD case isc_info_db_id: { diff --git a/src/jrd/Attachment.cpp b/src/jrd/Attachment.cpp index b4d32104f0..b380b6e748 100644 --- a/src/jrd/Attachment.cpp +++ b/src/jrd/Attachment.cpp @@ -221,6 +221,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb) att_context_vars(*pool), ddlTriggersContext(*pool), att_network_protocol(*pool), + att_remote_crypt(*pool), att_remote_address(*pool), att_remote_process(*pool), att_client_version(*pool), diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h index 847e45c00b..93769141f7 100644 --- a/src/jrd/Attachment.h +++ b/src/jrd/Attachment.h @@ -440,6 +440,7 @@ public: Firebird::StringMap att_context_vars; // Context variables for the connection Firebird::Stack ddlTriggersContext; // Context variables for DDL trigger event Firebird::string att_network_protocol; // Network protocol used by client for connection + Firebird::PathName att_remote_crypt; // Name of wire crypt plugin (if any) Firebird::string att_remote_address; // Protocol-specific address of remote client SLONG att_remote_pid; // Process id of remote client ULONG att_remote_flags; // Flags specific for server/client link diff --git a/src/jrd/Monitoring.cpp b/src/jrd/Monitoring.cpp index 7a9986cf9a..49a02453e9 100644 --- a/src/jrd/Monitoring.cpp +++ b/src/jrd/Monitoring.cpp @@ -978,6 +978,8 @@ void Monitoring::putAttachment(SnapshotData::DumpRecord& record, const Jrd::Atta record.storeString(f_mon_att_client_version, attachment->att_client_version); // remote protocol version record.storeString(f_mon_att_remote_version, attachment->att_remote_protocol); + // wire encryption plugin + record.storeString(f_mon_att_remote_crypt, attachment->att_remote_crypt); // remote host name record.storeString(f_mon_att_remote_host, attachment->att_remote_host); // OS user name diff --git a/src/jrd/SysFunction.cpp b/src/jrd/SysFunction.cpp index 9273c840a1..be5e09b45d 100644 --- a/src/jrd/SysFunction.cpp +++ b/src/jrd/SysFunction.cpp @@ -335,6 +335,7 @@ const char NETWORK_PROTOCOL_NAME[] = "NETWORK_PROTOCOL", WIRE_COMPRESSED_NAME[] = "WIRE_COMPRESSED", WIRE_ENCRYPTED_NAME[] = "WIRE_ENCRYPTED", + WIRE_CRYPT_PLUGIN_NAME[] = "WIRE_CRYPT_PLUGIN", CLIENT_ADDRESS_NAME[] = "CLIENT_ADDRESS", CLIENT_HOST_NAME[] = "CLIENT_HOST", CLIENT_PID_NAME[] = "CLIENT_PID", @@ -4048,6 +4049,13 @@ dsc* evlGetContext(thread_db* tdbb, const SysFunction*, const NestValueArray& ar resultStr = (attachment->att_remote_flags & isc_dpb_addr_flag_conn_encrypted) ? TRUE_VALUE : FALSE_VALUE; } + else if (nameStr == WIRE_CRYPT_PLUGIN_NAME) + { + if (attachment->att_remote_crypt.isEmpty()) + return NULL; + + resultStr = attachment->att_remote_crypt.ToString(); + } else if (nameStr == CLIENT_ADDRESS_NAME) { if (attachment->att_remote_address.isEmpty()) diff --git a/src/jrd/fields.h b/src/jrd/fields.h index 36f75f9497..aa60900fa4 100644 --- a/src/jrd/fields.h +++ b/src/jrd/fields.h @@ -208,4 +208,5 @@ FIELD(fld_tz_db_version , nam_tz_db_version , dtype_varying , 10 , dsc_text_type_ascii , NULL , true) - FIELD(fld_crypt_state , nam_crypt_state , dtype_short , sizeof(SSHORT) , 0 , NULL , true) \ No newline at end of file + FIELD(fld_crypt_state , nam_crypt_state , dtype_short , sizeof(SSHORT) , 0 , NULL , true) + FIELD(fld_remote_crypt , nam_wire_crypt_plugin, dtype_varying, MAX_SQL_IDENTIFIER_LEN , dsc_text_type_metadata , NULL , true) diff --git a/src/jrd/inf.cpp b/src/jrd/inf.cpp index 27babdf081..38b1a5a742 100644 --- a/src/jrd/inf.cpp +++ b/src/jrd/inf.cpp @@ -822,6 +822,19 @@ void INF_database_info(thread_db* tdbb, length = INF_convert(tdbb->getAttachment()->att_remote_flags, buffer); break; + case fb_info_wire_crypt: + { + const PathName& nm = tdbb->getAttachment()->att_remote_crypt; + if (!(info = INF_put_item(item, static_cast(nm.length()), nm.c_str(), info, end))) + { + if (transaction) + TRA_commit(tdbb, transaction, false); + + return; + } + } + continue; + case fb_info_statement_timeout_db: length = INF_convert(dbb->dbb_config->getStatementTimeout(), buffer); break; diff --git a/src/jrd/jrd.cpp b/src/jrd/jrd.cpp index 0a53d15f38..bc82593032 100644 --- a/src/jrd/jrd.cpp +++ b/src/jrd/jrd.cpp @@ -1065,6 +1065,7 @@ namespace Jrd PathName dpb_working_directory; string dpb_set_db_charset; string dpb_network_protocol; + PathName dpb_remote_crypt; string dpb_remote_address; string dpb_remote_host; string dpb_remote_os_user; @@ -6970,6 +6971,9 @@ void DatabaseOptions::get(const UCHAR* dpb, USHORT dpb_length, bool& invalid_cli case isc_dpb_addr_flags: dpb_remote_flags = address.getInt(); break; + case isc_dpb_addr_crypt: + address.getPath(dpb_remote_crypt); + break; default: break; } @@ -7275,6 +7279,7 @@ static JAttachment* create_attachment(const PathName& alias_name, attachment->att_filename = alias_name; attachment->att_network_protocol = options.dpb_network_protocol; + attachment->att_remote_crypt = options.dpb_remote_crypt; attachment->att_remote_address = options.dpb_remote_address; attachment->att_remote_pid = options.dpb_remote_pid; attachment->att_remote_flags = options.dpb_remote_flags; diff --git a/src/jrd/names.h b/src/jrd/names.h index 05b405cd47..6ebe4528c0 100644 --- a/src/jrd/names.h +++ b/src/jrd/names.h @@ -419,6 +419,7 @@ NAME("MON$STATEMENT_TIMER", nam_stmt_timer) NAME("MON$WIRE_COMPRESSED", nam_wire_compressed) NAME("MON$WIRE_ENCRYPTED", nam_wire_encrypted) +NAME("MON$WIRE_CRYPT_PLUGIN", nam_wire_crypt_plugin) NAME("RDB$TIME_ZONES", nam_time_zones) NAME("RDB$TIME_ZONE_ID", nam_tz_id) diff --git a/src/jrd/relations.h b/src/jrd/relations.h index 37ce864eb8..ceb93f0c6c 100644 --- a/src/jrd/relations.h +++ b/src/jrd/relations.h @@ -523,6 +523,7 @@ RELATION(nam_mon_attachments, rel_mon_attachments, ODS_11_1, rel_virtual) FIELD(f_mon_att_stmt_timeout, nam_stmt_timeout, fld_stmt_timeout, 0, ODS_13_0) FIELD(f_mon_att_wire_compressed, nam_wire_compressed, fld_bool, 0, ODS_13_0) FIELD(f_mon_att_wire_encrypted, nam_wire_encrypted, fld_bool, 0, ODS_13_0) + FIELD(f_mon_att_remote_crypt, nam_wire_crypt_plugin, fld_remote_crypt, 0, ODS_12_0) END_RELATION // Relation 35 (MON$TRANSACTIONS) diff --git a/src/remote/remote.h b/src/remote/remote.h index 6e575106fb..8ffa2f8ced 100644 --- a/src/remote/remote.h +++ b/src/remote/remote.h @@ -1093,6 +1093,7 @@ struct rem_port : public Firebird::GlobalStorage, public Firebird::RefCounted Firebird::IWireCryptPlugin* port_crypt_plugin; // plugin used by port, when not NULL - crypts wire data Firebird::ICryptKeyCallback* port_client_crypt_callback; // client callback to transfer database crypt key ServerCallbackBase* port_server_crypt_callback; // server callback to transfer database crypt key + Firebird::PathName port_crypt_name; // name of actual wire crypt plugin Firebird::RefPtr port_replicator; @@ -1138,8 +1139,8 @@ public: port_srv_auth(NULL), port_srv_auth_block(NULL), port_crypt_keys(getPool()), port_crypt_complete(false), port_crypt_level(WIRECRYPT_REQUIRED), port_known_server_keys(getPool()), port_crypt_plugin(NULL), - port_client_crypt_callback(NULL), port_server_crypt_callback(NULL), port_replicator(NULL), - port_buffer(FB_NEW_POOL(getPool()) UCHAR[rpt]), + port_client_crypt_callback(NULL), port_server_crypt_callback(NULL), port_crypt_name(getPool()), + port_replicator(NULL), port_buffer(FB_NEW_POOL(getPool()) UCHAR[rpt]), port_snd_packets(0), port_rcv_packets(0), port_snd_bytes(0), port_rcv_bytes(0) { addRef(); diff --git a/src/remote/server/server.cpp b/src/remote/server/server.cpp index 2a9c1a3825..425deb35e5 100644 --- a/src/remote/server/server.cpp +++ b/src/remote/server/server.cpp @@ -2328,7 +2328,10 @@ static void addClumplets(ClumpletWriter* dpb_buffer, flags |= isc_dpb_addr_flag_conn_compressed; #endif if (port->port_crypt_plugin) + { flags |= isc_dpb_addr_flag_conn_encrypted; + address_record.insertString(isc_dpb_addr_crypt, port->port_crypt_name); + } if (flags) address_record.insertInt(isc_dpb_addr_flags, flags); @@ -6175,6 +6178,7 @@ void rem_port::start_crypt(P_CRYPT * crypt, PACKET* sendL) port_crypt_plugin = cp.plugin(); port_crypt_plugin->addRef(); port_crypt_complete = true; + port_crypt_name = cp.name(); send_response(sendL, 0, 0, &st, false); WIRECRYPT_DEBUG(fprintf(stderr, "Srv: Installed cipher %s\n", cp.name())); From 236fc7ac14fc67ab779e759d2ee030ea4822de3b Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 14 Jan 2020 13:07:47 -0300 Subject: [PATCH 16/39] Added github action cronjob for automatic creation of tzdata update pull request. --- .github/workflows/tzdata-update.yml | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/tzdata-update.yml diff --git a/.github/workflows/tzdata-update.yml b/.github/workflows/tzdata-update.yml new file mode 100644 index 0000000000..7af28a4b59 --- /dev/null +++ b/.github/workflows/tzdata-update.yml @@ -0,0 +1,37 @@ +name: tzdata-update + +on: + schedule: + - cron: '0 11 * * *' + +jobs: + tzdata-update: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Checkout ICU + run: git clone --depth 1 https://github.com/unicode-org/icu-data.git -b master /tmp/icu-checkout + + - name: Check and update + run: | + VERSION=`ls /tmp/icu-checkout/tzdata/icunew/ -r1a |head -1` + echo Last version: $VERSION + + if [ "$VERSION" == "`cat tzdata/version.txt`" ] + then + exit + fi + + echo $VERSION > tzdata/version.txt + tzdata/update.sh + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: Updata tzdata. + title: Updata tzdata. + assignees: asfernandes + branch: work/tzdata-update From 98fe361f98ce130236681ea271a1b0402f7cbaac Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 16 Jan 2020 00:04:55 +0000 Subject: [PATCH 17/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 7c1443a4dd..9be0f3f4e8 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1726 + FORMAL BUILD NUMBER:1729 */ -#define PRODUCT_VER_STRING "4.0.0.1726" -#define FILE_VER_STRING "WI-T4.0.0.1726" -#define LICENSE_VER_STRING "WI-T4.0.0.1726" -#define FILE_VER_NUMBER 4, 0, 0, 1726 +#define PRODUCT_VER_STRING "4.0.0.1729" +#define FILE_VER_STRING "WI-T4.0.0.1729" +#define LICENSE_VER_STRING "WI-T4.0.0.1729" +#define FILE_VER_NUMBER 4, 0, 0, 1729 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1726" +#define FB_BUILD_NO "1729" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 97e03e1981..a7ebb3415b 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1726 +BuildNum=1729 NowAt=`pwd` cd `dirname $0` From 55ef2beb209e84ab3ccf4e6a20a0ea7dd185d39e Mon Sep 17 00:00:00 2001 From: Dimitry Sibiryakov Date: Wed, 15 Jan 2020 18:01:32 +0100 Subject: [PATCH 18/39] firebird.conf and databases.conf without .in suffix --- builds/install/arch-specific/solaris/CS/prototype.in | 2 +- builds/install/arch-specific/solaris/SS/prototype.in | 2 +- .../arch-specific/win32/BuildExecutableInstall.bat | 2 +- builds/install/misc/{databases.conf.in => databases.conf} | 0 builds/install/misc/{firebird.conf.in => firebird.conf} | 0 builds/win32/make_all.bat | 8 ++++---- builds/win32/make_boot.bat | 2 +- configure.ac | 4 ++-- src/CMakeLists.txt | 4 ++-- src/jrd/constants.h | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) rename builds/install/misc/{databases.conf.in => databases.conf} (100%) rename builds/install/misc/{firebird.conf.in => firebird.conf} (100%) diff --git a/builds/install/arch-specific/solaris/CS/prototype.in b/builds/install/arch-specific/solaris/CS/prototype.in index 1443a4748a..360c6bc1cf 100644 --- a/builds/install/arch-specific/solaris/CS/prototype.in +++ b/builds/install/arch-specific/solaris/CS/prototype.in @@ -18,7 +18,7 @@ d none @prefix@ 0751 firebird firebird v CONFIG.prsv @prefix@/security2.fdb=$SRCDIR/security2.fdb 0660 firebird firebird v CONFIG.prsv @prefix@/firebird.conf=$SRCDIR/misc/firebird.conf 0444 firebird firebird -v CONFIG.prsv @prefix@/databases.conf=$SRCDIR/../../builds/install/misc/databases.conf.in 0444 firebird firebird +v CONFIG.prsv @prefix@/databases.conf=$SRCDIR/../../builds/install/misc/databases.conf 0444 firebird firebird v CONFIG.prsv @prefix@/intl/fbintl.conf=$SRCDIR/misc/fbintl.conf 0644 firebird firebird f none @prefix@/CHANGELOG.md=$SRCDIR/../../CHANGELOG.md 0644 firebird firebird f none @prefix@/README.md=$SRCDIR/../../README.md 0644 firebird firebird diff --git a/builds/install/arch-specific/solaris/SS/prototype.in b/builds/install/arch-specific/solaris/SS/prototype.in index bb928b98a3..35bd67adb8 100644 --- a/builds/install/arch-specific/solaris/SS/prototype.in +++ b/builds/install/arch-specific/solaris/SS/prototype.in @@ -18,7 +18,7 @@ d none @prefix@ 0755 firebird firebird v CONFIG.prsv @prefix@/security2.fdb=$SRCDIR/security2.fdb 0660 firebird firebird v CONFIG.prsv @prefix@/firebird.conf=$SRCDIR/misc/firebird.conf 0644 firebird firebird -v CONFIG.prsv @prefix@/databases.conf=$SRCDIR/../../builds/install/misc/databases.conf.in 0544 firebird firebird +v CONFIG.prsv @prefix@/databases.conf=$SRCDIR/../../builds/install/misc/databases.conf 0544 firebird firebird v CONFIG.prsv @prefix@/intl/fbintl.conf=$SRCDIR/misc/fbintl.conf 0644 firebird firebird f none @prefix@/CHANGELOG.md=$SRCDIR/../../CHANGELOG.md 0644 firebird firebird f none @prefix@/README.md=$SRCDIR/../../README.md 0644 firebird firebird diff --git a/builds/install/arch-specific/win32/BuildExecutableInstall.bat b/builds/install/arch-specific/win32/BuildExecutableInstall.bat index 2c0ba91ce9..095c01c752 100644 --- a/builds/install/arch-specific/win32/BuildExecutableInstall.bat +++ b/builds/install/arch-specific/win32/BuildExecutableInstall.bat @@ -406,7 +406,7 @@ endlocal :: Generate sample databases file ::=============================== @echo Creating sample databases.conf -copy %FB_ROOT_PATH%\builds\install\misc\databases.conf.in %FB_OUTPUT_DIR%\databases.conf > nul +copy %FB_ROOT_PATH%\builds\install\misc\databases.conf %FB_OUTPUT_DIR%\databases.conf > nul ::End of DB_CONF ::----------------- diff --git a/builds/install/misc/databases.conf.in b/builds/install/misc/databases.conf similarity index 100% rename from builds/install/misc/databases.conf.in rename to builds/install/misc/databases.conf diff --git a/builds/install/misc/firebird.conf.in b/builds/install/misc/firebird.conf similarity index 100% rename from builds/install/misc/firebird.conf.in rename to builds/install/misc/firebird.conf diff --git a/builds/win32/make_all.bat b/builds/win32/make_all.bat index a7e2cbe8d2..698ae1bd50 100644 --- a/builds/win32/make_all.bat +++ b/builds/win32/make_all.bat @@ -63,10 +63,10 @@ for %%v in (gpre_boot build_msg codes) do ( ) :: Firebird.conf, etc -@copy %FB_GEN_DIR%\firebird.msg %FB_OUTPUT_DIR% > nul -@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in %FB_OUTPUT_DIR%\firebird.conf -@copy %FB_ROOT_PATH%\builds\install\misc\databases.conf.in %FB_OUTPUT_DIR%\databases.conf >nul -@copy %FB_ROOT_PATH%\builds\install\misc\fbintl.conf %FB_OUTPUT_DIR%\intl >nul +@copy %FB_GEN_DIR%\firebird.msg %FB_OUTPUT_DIR%\ > nul +@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf %FB_OUTPUT_DIR%\firebird.conf >nul +@copy %FB_ROOT_PATH%\builds\install\misc\databases.conf %FB_OUTPUT_DIR%\databases.conf >nul +@copy %FB_ROOT_PATH%\builds\install\misc\fbintl.conf %FB_OUTPUT_DIR%\intl\ >nul @copy %FB_ROOT_PATH%\builds\install\misc\plugins.conf %FB_OUTPUT_DIR% >nul @copy %FB_ROOT_PATH%\builds\install\misc\replication.conf %FB_OUTPUT_DIR% >nul @copy %FB_ROOT_PATH%\src\utilities\ntrace\fbtrace.conf %FB_OUTPUT_DIR% >nul diff --git a/builds/win32/make_boot.bat b/builds/win32/make_boot.bat index dd00e6e3bd..d7c77277d1 100644 --- a/builds/win32/make_boot.bat +++ b/builds/win32/make_boot.bat @@ -75,7 +75,7 @@ if "%ERRLEV%"=="1" goto :END call :isql if "%ERRLEV%"=="1" goto :END -@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf.in %FB_BIN_DIR%\firebird.conf +@copy %FB_ROOT_PATH%\builds\install\misc\firebird.conf %FB_BIN_DIR%\firebird.conf :: Copy ICU and zlib both to Debug and Release configurations diff --git a/configure.ac b/configure.ac index 8dead2da79..c0e1398f62 100644 --- a/configure.ac +++ b/configure.ac @@ -1251,8 +1251,8 @@ dnl common files for all posix hosts dnl TODO: fix "arch-specific/linux/" paths for common posix scripts with SVN for fb_tgt in $FB_TARGETS; do AC_CONFIG_FILES([ -gen/$fb_tgt/firebird/firebird.conf:builds/install/misc/firebird.conf.in -gen/$fb_tgt/firebird/databases.conf:builds/install/misc/databases.conf.in +gen/$fb_tgt/firebird/firebird.conf:builds/install/misc/firebird.conf +gen/$fb_tgt/firebird/databases.conf:builds/install/misc/databases.conf gen/$fb_tgt/firebird/fbtrace.conf:src/utilities/ntrace/fbtrace.conf gen/$fb_tgt/firebird/intl/fbintl.conf:builds/install/misc/fbintl.conf gen/$fb_tgt/firebird/plugins.conf:builds/install/misc/plugins.conf diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b46b91ec12..b890c4ea8b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -909,8 +909,8 @@ add_custom_target(copy_files COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/security.fdb ${output_dir}/security4.fdb COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GENERATED_DIR}/help.fdb ${output_dir}/help/help.fdb # configs, text files - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf.in ${output_dir}/firebird.conf - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf.in ${output_dir}/databases.conf + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/firebird.conf ${output_dir}/firebird.conf + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/databases.conf ${output_dir}/databases.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/fbintl.conf ${output_dir}/intl/fbintl.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/plugins.conf ${output_dir}/plugins.conf COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/builds/install/misc/IPLicense.txt ${output_dir}/IPLicense.txt diff --git a/src/jrd/constants.h b/src/jrd/constants.h index 8e0268cc77..72b463455f 100644 --- a/src/jrd/constants.h +++ b/src/jrd/constants.h @@ -62,7 +62,7 @@ const int TEMP_STR_LENGTH = 128; // Metadata constants // When changing these constants, change MaxIdentifierByteLength and MaxIdentifierCharLength in -// firebird.conf.in too. +// firebird.conf too. const unsigned METADATA_IDENTIFIER_CHAR_LEN = 63; const unsigned METADATA_BYTES_PER_CHAR = 4; From 473afd3df809d64ae3b6f224b4a569e6bc4589b2 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Thu, 16 Jan 2020 17:32:43 +0300 Subject: [PATCH 19/39] An attempt to fix CORE-6218: COUNT(DISTINCT ) leads FB to crash when there are duplicate values of this field --- src/jrd/sort.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/jrd/sort.cpp b/src/jrd/sort.cpp index f893fb044d..f44bc99bd3 100644 --- a/src/jrd/sort.cpp +++ b/src/jrd/sort.cpp @@ -819,15 +819,14 @@ void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) break; case SKD_dec64: - if (direction && !duplicateHandling) + fb_assert(false); // diddleKey for Dec64/128 not tested on bigendians! + if (direction) { ((Decimal64*) p)->makeKey(lwp); *p ^= 1 << 7; } else if (!(key->skd_flags & SKD_separate_data)) { - fb_assert(false); - if (complement && n) { UCHAR* pp = p; @@ -843,15 +842,13 @@ void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) case SKD_dec128: fb_assert(false); // diddleKey for Dec64/128 not tested on bigendians! - if (direction && !duplicateHandling) + if (direction) { ((Decimal128*) p)->makeKey(lwp); *p ^= 1 << 7; } else if (!(key->skd_flags & SKD_separate_data)) { - fb_assert(false); - if (complement && n) { UCHAR* pp = p; @@ -1133,15 +1130,13 @@ void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) #endif // IEEE case SKD_dec64: - if (direction && !duplicateHandling) + if (direction) { ((Decimal64*) p)->makeKey(lwp); p[3] ^= 1 << 7; } else if (!(key->skd_flags & SKD_separate_data)) { - fb_assert(false); - if (complement && n) { UCHAR* pp = p; @@ -1156,15 +1151,13 @@ void Sort::diddleKey(UCHAR* record, bool direction, bool duplicateHandling) break; case SKD_dec128: - if (direction && !duplicateHandling) + if (direction) { ((Decimal128*) p)->makeKey(lwp); p[3] ^= 1 << 7; } else if (!(key->skd_flags & SKD_separate_data)) { - fb_assert(false); - if (complement && n) { UCHAR* pp = p; From 9720b5d10c8f691afab1a96a463dfa881b7b9e9c Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 17 Jan 2020 00:04:36 +0000 Subject: [PATCH 20/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 9be0f3f4e8..840d7d5a09 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1729 + FORMAL BUILD NUMBER:1731 */ -#define PRODUCT_VER_STRING "4.0.0.1729" -#define FILE_VER_STRING "WI-T4.0.0.1729" -#define LICENSE_VER_STRING "WI-T4.0.0.1729" -#define FILE_VER_NUMBER 4, 0, 0, 1729 +#define PRODUCT_VER_STRING "4.0.0.1731" +#define FILE_VER_STRING "WI-T4.0.0.1731" +#define LICENSE_VER_STRING "WI-T4.0.0.1731" +#define FILE_VER_NUMBER 4, 0, 0, 1731 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1729" +#define FB_BUILD_NO "1731" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index a7ebb3415b..263b7217af 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1729 +BuildNum=1731 NowAt=`pwd` cd `dirname $0` From be2d7718c8964af23c798a7431a7764167e5266e Mon Sep 17 00:00:00 2001 From: hvlad Date: Fri, 17 Jan 2020 15:14:53 +0200 Subject: [PATCH 21/39] Fixed bug CORE-6231 : access violation on shutdown of xnet connection to local database when events have been registered --- src/remote/client/interface.cpp | 9 ++++++++- src/remote/os/win32/wnet.cpp | 15 ++++++++++++--- src/remote/os/win32/xnet.cpp | 11 +++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/remote/client/interface.cpp b/src/remote/client/interface.cpp index 18fa388fbb..abb2ecbfda 100644 --- a/src/remote/client/interface.cpp +++ b/src/remote/client/interface.cpp @@ -7204,7 +7204,14 @@ static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM arg) P_OP operation = op_void; { // scope RefMutexGuard portGuard(*port->port_sync, FB_FUNCTION); - stuff = port->receive(&packet); + try + { + stuff = port->receive(&packet); + } + catch(status_exception&) + { + // ignore + } operation = packet.p_operation; diff --git a/src/remote/os/win32/wnet.cpp b/src/remote/os/win32/wnet.cpp index b551112bd9..11c1fb939c 100644 --- a/src/remote/os/win32/wnet.cpp +++ b/src/remote/os/win32/wnet.cpp @@ -759,7 +759,11 @@ static void disconnect(rem_port* port) } wnet_ports->unRegisterPort(port); - port->release(); + + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_threadId)) + port->port_thread_guard->setWait(port->port_events_thread); + else + port->release(); } @@ -1332,7 +1336,7 @@ static bool packet_receive(rem_port* port, UCHAR* buffer, SSHORT buffer_length, if (!n) { - if (port->port_flags & PORT_detached) + if (port->port_flags & (PORT_detached | PORT_disconnect)) return false; return wnet_error(port, "ReadFile end-of-file", isc_net_read_err, dwError); @@ -1408,10 +1412,15 @@ static bool packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_leng status = GetOverlappedResult(port->port_pipe, &ovrl, &n, TRUE); dwError = GetLastError(); } - if (!status) + if (!status && dwError != ERROR_NO_DATA) return wnet_error(port, "WriteFile", isc_net_write_err, dwError); if (n != length) + { + if (port->port_flags & (PORT_detached | PORT_disconnect)) + return false; + return wnet_error(port, "WriteFile truncated", isc_net_write_err, dwError); + } #if defined(DEBUG) && defined(WNET_trace) packet_print("send", reinterpret_cast(buffer), buffer_length); diff --git a/src/remote/os/win32/xnet.cpp b/src/remote/os/win32/xnet.cpp index 7385d0c09e..482f14a1f4 100644 --- a/src/remote/os/win32/xnet.cpp +++ b/src/remote/os/win32/xnet.cpp @@ -1068,6 +1068,14 @@ static void cleanup_port(rem_port* port) * **************************************/ + if (port->port_thread_guard && port->port_events_thread && !Thread::isCurrent(port->port_events_threadId)) + { + //port->port_thread_guard->setWait(port->port_events_thread); + + // Do not release XNET structures while event's thread working + Thread::waitForCompletion(port->port_events_thread); + } + if (port->port_xcc) { cleanup_comm(port->port_xcc); @@ -1996,6 +2004,9 @@ static bool_t xnet_read(XDR* xdrs) const DWORD wait_result = WaitForSingleObject(xcc->xcc_event_recv_channel_filled, XNET_RECV_WAIT_TIMEOUT); + if (port->port_flags & PORT_disconnect) + return FALSE; + if (wait_result == WAIT_OBJECT_0) { // Client has written some data for us (server) to read From 1f32a12b90c4d41307e83d6c6003d36b99133749 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Sat, 18 Jan 2020 00:04:35 +0000 Subject: [PATCH 22/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 840d7d5a09..0b3ba635c8 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1731 + FORMAL BUILD NUMBER:1732 */ -#define PRODUCT_VER_STRING "4.0.0.1731" -#define FILE_VER_STRING "WI-T4.0.0.1731" -#define LICENSE_VER_STRING "WI-T4.0.0.1731" -#define FILE_VER_NUMBER 4, 0, 0, 1731 +#define PRODUCT_VER_STRING "4.0.0.1732" +#define FILE_VER_STRING "WI-T4.0.0.1732" +#define LICENSE_VER_STRING "WI-T4.0.0.1732" +#define FILE_VER_NUMBER 4, 0, 0, 1732 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1731" +#define FB_BUILD_NO "1732" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 263b7217af..9fe5324fae 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1731 +BuildNum=1732 NowAt=`pwd` cd `dirname $0` From 2a6d7097448aee29435369f1fb8c1429bf04b287 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Sun, 19 Jan 2020 12:35:28 +0300 Subject: [PATCH 23/39] Fixed wrong parameters order. Thanks to DS --- src/burp/restore.epp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 9493ae7fa8..0cce0e69f0 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -1090,7 +1090,7 @@ void create_database(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TE if (!tdgbl->gbl_sw_crypt) { - BURP_error(true, 378); + BURP_error(378, true); // Unknown crypt plugin name - use -CRYPT switch } From a238ca5eba6d259565138bafe3098d69bcf47d6d Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Mon, 20 Jan 2020 00:04:31 +0000 Subject: [PATCH 24/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 0b3ba635c8..067c443900 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1732 + FORMAL BUILD NUMBER:1733 */ -#define PRODUCT_VER_STRING "4.0.0.1732" -#define FILE_VER_STRING "WI-T4.0.0.1732" -#define LICENSE_VER_STRING "WI-T4.0.0.1732" -#define FILE_VER_NUMBER 4, 0, 0, 1732 +#define PRODUCT_VER_STRING "4.0.0.1733" +#define FILE_VER_STRING "WI-T4.0.0.1733" +#define LICENSE_VER_STRING "WI-T4.0.0.1733" +#define FILE_VER_NUMBER 4, 0, 0, 1733 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1732" +#define FB_BUILD_NO "1733" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 9fe5324fae..940745e82a 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1732 +BuildNum=1733 NowAt=`pwd` cd `dirname $0` From 5f1ea284dc27e5421405d7c8148550e0a98aa47d Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sun, 19 Jan 2020 23:08:32 -0300 Subject: [PATCH 25/39] Fixed CORE-6116 - The Metadata script extracted using ISQL of a database restored from a Firebird 2.5.9 Backup is invalid/incorrect when table has COMPUTED BY field. --- src/isql/extract.epp | 44 +++++++++++++++++++++++++++---------------- src/isql/isql.epp | 28 +++++++++++++++++++++++++++ src/isql/isql_proto.h | 4 ++++ 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/isql/extract.epp b/src/isql/extract.epp index 33ecd7a499..1b720d6822 100644 --- a/src/isql/extract.epp +++ b/src/isql/extract.epp @@ -417,10 +417,13 @@ int EXTRACT_list_table(const SCHAR* relation_name, if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) { - if (FLD.RDB$CHARACTER_LENGTH.NULL) - isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH); - else - isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH); + isqlGlob.printf("(%d)", + ISQL_get_char_length( + FLD.RDB$FIELD_LENGTH, + FLD.RDB$CHARACTER_LENGTH.NULL, FLD.RDB$CHARACTER_LENGTH, + FLD.RDB$CHARACTER_SET_ID.NULL, FLD.RDB$CHARACTER_SET_ID + ) + ); } // Catch arrays after printing the type @@ -833,10 +836,13 @@ static void get_procedure_args(const char* proc_name) // FSG 18.Nov.2000 if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) { - if (FLD.RDB$CHARACTER_LENGTH.NULL) - isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH); - else - isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH); + isqlGlob.printf("(%d)", + ISQL_get_char_length( + FLD.RDB$FIELD_LENGTH, + FLD.RDB$CHARACTER_LENGTH.NULL, FLD.RDB$CHARACTER_LENGTH, + FLD.RDB$CHARACTER_SET_ID.NULL, FLD.RDB$CHARACTER_SET_ID + ) + ); } // Show international character sets and collations @@ -1054,10 +1060,13 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg) // FSG 18.Nov.2000 if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) { - if (FLD.RDB$CHARACTER_LENGTH.NULL) - isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH); - else - isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH); + isqlGlob.printf("(%d)", + ISQL_get_char_length( + FLD.RDB$FIELD_LENGTH, + FLD.RDB$CHARACTER_LENGTH.NULL, FLD.RDB$CHARACTER_LENGTH, + FLD.RDB$CHARACTER_SET_ID.NULL, FLD.RDB$CHARACTER_SET_ID + ) + ); } // Show international character sets and collations @@ -2624,10 +2633,13 @@ static void listRelationComputed(LegacyTables flag, SSHORT default_char_set_id) if ((FLD.RDB$FIELD_TYPE == T_CHAR) || (FLD.RDB$FIELD_TYPE == VARCHAR)) { - if (FLD.RDB$CHARACTER_LENGTH.NULL) - isqlGlob.printf("(%d)", FLD.RDB$FIELD_LENGTH); - else - isqlGlob.printf("(%d)", FLD.RDB$CHARACTER_LENGTH); + isqlGlob.printf("(%d)", + ISQL_get_char_length( + FLD.RDB$FIELD_LENGTH, + FLD.RDB$CHARACTER_LENGTH.NULL, FLD.RDB$CHARACTER_LENGTH, + FLD.RDB$CHARACTER_SET_ID.NULL, FLD.RDB$CHARACTER_SET_ID + ) + ); } // Catch arrays after printing the type diff --git a/src/isql/isql.epp b/src/isql/isql.epp index 033194a87f..059d4a8d9e 100644 --- a/src/isql/isql.epp +++ b/src/isql/isql.epp @@ -1211,6 +1211,34 @@ SSHORT ISQL_get_field_length(const TEXT* field_name) } +SSHORT ISQL_get_char_length( + SSHORT fieldLength, + SSHORT characterLengthNull, SSHORT characterLength, + SSHORT characterSetIdNull, SSHORT characterSetId) +{ + if (characterLengthNull || characterLength == 0) + { + if (!characterSetIdNull) + { + FOR CS IN RDB$CHARACTER_SETS + WITH CS.RDB$CHARACTER_SET_ID EQ characterSetId AND + CS.RDB$BYTES_PER_CHARACTER > 0 + { + fieldLength /= CS.RDB$BYTES_PER_CHARACTER; + } + END_FOR + ON_ERROR + ISQL_errmsg(fbStatus); + END_ERROR; + } + + return fieldLength; + } + else + return characterLength; +} + + void ISQL_get_character_sets(SSHORT char_set_id, SSHORT collation, bool collate_only, bool not_null, bool quote, TEXT* string) { diff --git a/src/isql/isql_proto.h b/src/isql/isql_proto.h index 5a7b79c536..52a83c5cfa 100644 --- a/src/isql/isql_proto.h +++ b/src/isql/isql_proto.h @@ -45,6 +45,10 @@ void ISQL_get_character_sets(SSHORT, SSHORT, bool, bool, bool, TEXT*); SSHORT ISQL_get_default_char_set_id(); void ISQL_get_default_source(const TEXT*, TEXT*, ISC_QUAD*); SSHORT ISQL_get_field_length(const TEXT*); +SSHORT ISQL_get_char_length( + SSHORT fieldLength, + SSHORT characterLengthNull, SSHORT characterLength, + SSHORT characterSetIdNull, SSHORT characterSetId); SLONG ISQL_get_index_segments(TEXT*, const size_t, const TEXT*, bool); bool ISQL_get_null_flag(const TEXT*, TEXT*); void ISQL_get_version(bool); From d24b4c96bd0a0a2dadcf1018b0686b8fe0799722 Mon Sep 17 00:00:00 2001 From: hvlad Date: Mon, 20 Jan 2020 14:31:42 +0200 Subject: [PATCH 26/39] Call of TimeZoneUtil::initTimeZoneEnv() is moved to the InitPrefix::init() to avoid too early initialization of default config file on Windows. Current code attempts to load firebird.conf from .exe folder (should be loaded from fbclient.dll folder). --- src/yvalve/gds.cpp | 2 ++ src/yvalve/why.cpp | 14 -------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp index c0dd855594..afab931314 100644 --- a/src/yvalve/gds.cpp +++ b/src/yvalve/gds.cpp @@ -3930,6 +3930,8 @@ public: } msgPrefix.copyTo(fb_prefix_msg_val, sizeof(fb_prefix_msg_val)); fb_prefix_msg = fb_prefix_msg_val; + + TimeZoneUtil::initTimeZoneEnv(); } static void cleanup() { diff --git a/src/yvalve/why.cpp b/src/yvalve/why.cpp index 1fc9754034..1df43ca04b 100644 --- a/src/yvalve/why.cpp +++ b/src/yvalve/why.cpp @@ -40,7 +40,6 @@ #include "../common/StatementMetadata.h" #include "../common/StatusHolder.h" #include "../common/ThreadStart.h" -#include "../common/TimeZoneUtil.h" #include "../common/isc_proto.h" #include "../common/isc_f_proto.h" #include "../common/utils_proto.h" @@ -738,19 +737,6 @@ RefPtr translateHandle(GlobalPtr //------------------------------------- -class TimeZoneDataInit -{ -public: - explicit TimeZoneDataInit(MemoryPool&) - { - TimeZoneUtil::initTimeZoneEnv(); - } -}; - -static GlobalPtr timeZoneDataInit; - -//------------------------------------- - const int SHUTDOWN_TIMEOUT = 5000; // 5 sec class ShutdownInit From d8be3d534fcafc2e8898013d6da566a88b33da97 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 20 Jan 2020 19:19:48 +0300 Subject: [PATCH 27/39] Add chacha to default config and use it when available. Clients, missing required plugin, will continue using rc4. --- builds/install/misc/firebird.conf | 12 +++++++----- src/common/config/config.cpp | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/builds/install/misc/firebird.conf b/builds/install/misc/firebird.conf index f627cd464e..897e583e66 100644 --- a/builds/install/misc/firebird.conf +++ b/builds/install/misc/firebird.conf @@ -446,8 +446,8 @@ #AuthClient = Srp256, Srp, Legacy_Auth #Non Windows clients #AuthClient = Srp256, Srp, Win_Sspi, Legacy_Auth #Windows clients # -# If you need to use server plugins that do not provide encryption key (both Legacy_Auth -# & Win_Sspi) you should also turn off required encryption on the wire with WireCrypt +# If you need to use server plugins that do not provide encryption key (Legacy_Auth is the +# only such std plugin) you should also turn off required encryption on the wire with WireCrypt # configuration parameter except when working with the XNET protocol which is never encrypted. # @@ -466,12 +466,14 @@ #TracePlugin = fbtrace # Wire crypt plugins are used to crypt data transferred over the wire. -# In default case wire is encrypted using Alleged RC4 -# (key must be generated by auth plugin). +# In default case wire is encrypted using ChaCha#20 or Alleged RC4. +# Key must be generated by auth plugin. +# For chacha we are using 16 or 32 bytes key (depends upon what is provided +# by auth plugin), 12 bytes nonce and 4 bytes counter, 20 (10 + 10) rounds are made. # # Per-connection configurable. # -#WireCryptPlugin = Arc4 +#WireCryptPlugin = ChaCha, Arc4 # Key holder is a kind of temp storage for DB crypt keys. # There is no default for this kind of plugins. diff --git a/src/common/config/config.cpp b/src/common/config/config.cpp index ddfe804adb..e2573d8140 100644 --- a/src/common/config/config.cpp +++ b/src/common/config/config.cpp @@ -204,7 +204,7 @@ const Config::ConfigEntry Config::entries[MAX_CONFIG_KEY] = {TYPE_STRING, "SecurityDatabase", (ConfigValue) "security.db"}, // sec/db alias - rely on databases.conf {TYPE_STRING, "ServerMode", (ConfigValue) ""}, // actual value differs in boot/regular cases {TYPE_STRING, "WireCrypt", (ConfigValue) NULL}, - {TYPE_STRING, "WireCryptPlugin", (ConfigValue) "Arc4"}, + {TYPE_STRING, "WireCryptPlugin", (ConfigValue) "ChaCha, Arc4"}, {TYPE_STRING, "KeyHolderPlugin", (ConfigValue) ""}, {TYPE_BOOLEAN, "RemoteAccess", (ConfigValue) true}, {TYPE_BOOLEAN, "IPv6V6Only", (ConfigValue) false}, From 0a48a5e8357cf21a25edd83b70a5d8b158d76fb8 Mon Sep 17 00:00:00 2001 From: AlexPeshkoff Date: Mon, 20 Jan 2020 20:18:15 +0300 Subject: [PATCH 28/39] This should fix MacOS build --- src/plugins/crypt/chacha/ChaCha.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/crypt/chacha/ChaCha.cpp b/src/plugins/crypt/chacha/ChaCha.cpp index 7331c6a899..218bd3c7c7 100644 --- a/src/plugins/crypt/chacha/ChaCha.cpp +++ b/src/plugins/crypt/chacha/ChaCha.cpp @@ -168,7 +168,7 @@ SimpleFactory factory; } // anonymous namespace -extern "C" void FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) +extern "C" void FB_EXPORTED FB_PLUGIN_ENTRY_POINT(Firebird::IMaster* master) { CachedMasterInterface::set(master); PluginManagerInterfacePtr()->registerPluginFactory(IPluginManager::TYPE_WIRE_CRYPT, "ChaCha", &factory); From a31b3410cc3fc84b23593f6d28205e404cfd0782 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Tue, 21 Jan 2020 00:04:40 +0000 Subject: [PATCH 29/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 067c443900..35093fe8b7 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1733 + FORMAL BUILD NUMBER:1737 */ -#define PRODUCT_VER_STRING "4.0.0.1733" -#define FILE_VER_STRING "WI-T4.0.0.1733" -#define LICENSE_VER_STRING "WI-T4.0.0.1733" -#define FILE_VER_NUMBER 4, 0, 0, 1733 +#define PRODUCT_VER_STRING "4.0.0.1737" +#define FILE_VER_STRING "WI-T4.0.0.1737" +#define LICENSE_VER_STRING "WI-T4.0.0.1737" +#define FILE_VER_NUMBER 4, 0, 0, 1737 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1733" +#define FB_BUILD_NO "1737" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 940745e82a..47d4f35077 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1733 +BuildNum=1737 NowAt=`pwd` cd `dirname $0` From 5d1bcc284c6e444b6232dd544c4d81dd6c922807 Mon Sep 17 00:00:00 2001 From: Dimitry Sibiryakov Date: Mon, 20 Jan 2020 17:36:24 +0100 Subject: [PATCH 30/39] Generate ids.h without m4 --- builds/mac_os_x/CS/CS.pbproj/project.pbxproj | 5 - builds/posix/Makefile.in | 17 +- src/include/gen/ids.h | 708 ------------------- src/jrd/DbCreators.cpp | 2 +- src/jrd/Mapping.cpp | 2 +- src/jrd/TimeZone.cpp | 2 +- src/jrd/UserManagement.cpp | 2 +- src/jrd/ids.h | 89 +++ src/jrd/ini.epp | 2 +- src/jrd/replication/Applier.cpp | 2 +- src/jrd/vio.cpp | 2 +- src/misc/ids.m | 30 - 12 files changed, 97 insertions(+), 766 deletions(-) delete mode 100644 src/include/gen/ids.h create mode 100644 src/jrd/ids.h delete mode 100644 src/misc/ids.m diff --git a/builds/mac_os_x/CS/CS.pbproj/project.pbxproj b/builds/mac_os_x/CS/CS.pbproj/project.pbxproj index 9c84eabf94..82eb6a0601 100644 --- a/builds/mac_os_x/CS/CS.pbproj/project.pbxproj +++ b/builds/mac_os_x/CS/CS.pbproj/project.pbxproj @@ -4411,11 +4411,6 @@ path = ids.h; refType = 4; }; - F616C6050200B0CF01EF0ADE = { - isa = PBXFileReference; - path = ids.m; - refType = 4; - }; F616C6060200B0CF01EF0ADE = { isa = PBXFileReference; path = idx.cpp; diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index 1d97d66a6b..3f05cd22ac 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -226,7 +226,7 @@ $(TOMCRYPT_LIB): $(TOM_Objs) # main build target for both debug and release builds # -.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest +.PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes examples cross_rest master_process: ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h @@ -236,10 +236,6 @@ master_process: $(MAKE) updateCloopInterfaces $(MAKE) boot $(MAKE) yvalve -ifeq ($(IsDeveloper), Y) -# In developer mode we must regenerate various files in include/gen - $(MAKE) ids -endif $(MAKE) engine $(MAKE) fbintl $(MAKE) utilities @@ -271,10 +267,6 @@ cross1: $(MAKE) updateCloopInterfaces $(MAKE) boot $(MAKE) yvalve -ifeq ($(IsDeveloper), Y) -# In developer mode we must regenerate various files in include/gen - $(MAKE) ids -endif $(MAKE) engine $(MAKE) fbintl $(MAKE) gbak isql gfix @@ -590,22 +582,15 @@ $(COMPAT_SQL): $(SRC_COMPAT_SQL) .PHONY: gen_codes CODES = $(BIN)/codes$(EXEC_EXT) -IDS = $(SRC_ROOT)/include/gen/ids.h codes: gen_codes -ids: $(IDS) - gen_codes: $(CODES) msg.timestamp $(CODES) $(SRC_ROOT)/include/gen $(LNG_ROOT) $(CODES): $(CODES_Objects) $(COMMON_LIB) $(EXE_LINK) $(EXE_LINK_OPTIONS) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,..) -$(IDS): $(SRC_ROOT)/misc/ids.m $(SRC_ROOT)/jrd/relations.h - m4 $< > $@ - - #___________________________________________________________________________ # all the rest we need to build # diff --git a/src/include/gen/ids.h b/src/include/gen/ids.h deleted file mode 100644 index 31cf55039c..0000000000 --- a/src/include/gen/ids.h +++ /dev/null @@ -1,708 +0,0 @@ - -/* - * PROGRAM: JRD Access Method - * MODULE: relations.h - * DESCRIPTION: System relation definitions - * - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -// Order of relations in this file affect their IDs, -// so please add new relations to the end of the list - -// Relation 0 (RDB$PAGES) - - const USHORT f_pag_page = 0; - const USHORT f_pag_id = 1; - const USHORT f_pag_seq = 2; - const USHORT f_pag_type = 3; - - -// Relation 1 (RDB$DATABASE) - - const USHORT f_dat_desc = 0; - const USHORT f_dat_id = 1; - const USHORT f_dat_class = 2; - const USHORT f_dat_charset = 3; - const USHORT f_dat_linger = 4; - const USHORT f_dat_sql_security = 5; - - -// Relation 2 (RDB$FIELDS) - - const USHORT f_fld_name = 0; - const USHORT f_fld_qname = 1; - const USHORT f_fld_v_blr = 2; - const USHORT f_fld_v_source = 3; - const USHORT f_fld_computed = 4; - const USHORT f_fld_csource = 5; - const USHORT f_fld_default = 6; - const USHORT f_fld_dsource = 7; - const USHORT f_fld_length = 8; - const USHORT f_fld_scale = 9; - const USHORT f_fld_type = 10; - const USHORT f_fld_sub_type = 11; - const USHORT f_fld_missing = 12; - const USHORT f_fld_msource = 13; - const USHORT f_fld_desc = 14; - const USHORT f_fld_sys_flag = 15; - const USHORT f_fld_qheader = 16; - const USHORT f_fld_seg_len = 17; - const USHORT f_fld_estring = 18; - const USHORT f_fld_ext_length = 19; - const USHORT f_fld_ext_scale = 20; - const USHORT f_fld_ext_type = 21; - const USHORT f_fld_dimensions = 22; - const USHORT f_fld_null_flag = 23; - const USHORT f_fld_char_length = 24; - const USHORT f_fld_coll_id = 25; - const USHORT f_fld_charset_id = 26; - const USHORT f_fld_precision = 27; - const USHORT f_fld_class = 28; - const USHORT f_fld_owner = 29; - - -// Relation 3 (RDB$INDEX_SEGMENTS) - - const USHORT f_seg_name = 0; - const USHORT f_seg_field = 1; - const USHORT f_seg_position = 2; - const USHORT f_seg_statistics = 3; - - -// Relation 4 (RDB$INDICES) - - const USHORT f_idx_name = 0; - const USHORT f_idx_relation = 1; - const USHORT f_idx_id = 2; - const USHORT f_idx_flag = 3; - const USHORT f_idx_desc = 4; - const USHORT f_idx_count = 5; - const USHORT f_idx_inactive = 6; - const USHORT f_idx_type = 7; - const USHORT f_idx_foreign = 8; - const USHORT f_idx_sys_flag = 9; - const USHORT f_idx_exp_blr = 10; - const USHORT f_idx_exp_source = 11; - const USHORT f_idx_statistics = 12; - - -// Relation 5 (RDB$RELATION_FIELDS) - - const USHORT f_rfr_fname = 0; - const USHORT f_rfr_rname = 1; - const USHORT f_rfr_sname = 2; - const USHORT f_rfr_qname = 3; - const USHORT f_rfr_base = 4; - const USHORT f_rfr_estring = 5; - const USHORT f_rfr_position = 6; - const USHORT f_rfr_qheader = 7; - const USHORT f_rfr_flag = 8; - const USHORT f_rfr_id = 9; - const USHORT f_rfr_context = 10; - const USHORT f_rfr_desc = 11; - const USHORT f_rfr_default = 12; - const USHORT f_rfr_sys_flag = 13; - const USHORT f_rfr_class = 14; - const USHORT f_rfr_complex = 15; - const USHORT f_rfr_null_flag = 16; - const USHORT f_rfr_dsource = 17; - const USHORT f_rfr_coll_id = 18; - const USHORT f_rfr_gen_name = 19; - const USHORT f_rfr_identity_type = 20; - - -// Relation 6 (RDB$RELATIONS) - - const USHORT f_rel_blr = 0; - const USHORT f_rel_source = 1; - const USHORT f_rel_desc = 2; - const USHORT f_rel_id = 3; - const USHORT f_rel_sys_flag = 4; - const USHORT f_rel_key_len = 5; - const USHORT f_rel_format = 6; - const USHORT f_rel_field_id = 7; - const USHORT f_rel_name = 8; - const USHORT f_rel_class = 9; - const USHORT f_rel_ext_file = 10; - const USHORT f_rel_runtime = 11; - const USHORT f_rel_ext_desc = 12; - const USHORT f_rel_owner = 13; - const USHORT f_rel_def_class = 14; - const USHORT f_rel_flags = 15; - const USHORT f_rel_type = 16; - const USHORT f_rel_sql_security = 17; - - -// Relation 7 (RDB$VIEW_RELATIONS) - - const USHORT f_vrl_vname = 0; - const USHORT f_vrl_rname = 1; - const USHORT f_vrl_context = 2; - const USHORT f_vrl_cname = 3; - const USHORT f_vrl_context_type = 4; - const USHORT f_vrl_pkg_name = 5; - - -// Relation 8 (RDB$FORMATS) - - const USHORT f_fmt_rid = 0; - const USHORT f_fmt_format = 1; - const USHORT f_fmt_desc = 2; - - -// Relation 9 (RDB$SECURITY_CLASSES) - - const USHORT f_cls_class = 0; - const USHORT f_cls_acl = 1; - const USHORT f_cls_desc = 2; - - -// Relation 10 (RDB$FILES) - - const USHORT f_file_name = 0; - const USHORT f_file_seq = 1; - const USHORT f_file_start = 2; - const USHORT f_file_length = 3; - const USHORT f_file_flags = 4; - const USHORT f_file_shad_num = 5; - - -// Relation 11 (RDB$TYPES) - - const USHORT f_typ_field = 0; - const USHORT f_typ_type = 1; - const USHORT f_typ_name = 2; - const USHORT f_typ_desc = 3; - const USHORT f_typ_sys_flag = 4; - - -// Relation 12 (RDB$TRIGGERS) - - const USHORT f_trg_name = 0; - const USHORT f_trg_rname = 1; - const USHORT f_trg_seq = 2; - const USHORT f_trg_type = 3; - const USHORT f_trg_source = 4; - const USHORT f_trg_blr = 5; - const USHORT f_trg_desc = 6; - const USHORT f_trg_inactive = 7; - const USHORT f_trg_sys_flag = 8; - const USHORT f_trg_flags = 9; - const USHORT f_trg_valid_blr = 10; - const USHORT f_trg_debug_info = 11; - const USHORT f_trg_engine_name = 12; - const USHORT f_trg_entry = 13; - const USHORT f_trg_sql_security = 14; - - -// Relation 13 (RDB$DEPENDENCIES) - - const USHORT f_dpd_name = 0; - const USHORT f_dpd_o_name = 1; - const USHORT f_dpd_f_name = 2; - const USHORT f_dpd_type = 3; - const USHORT f_dpd_o_type = 4; - const USHORT f_dpd_pkg_name = 5; - - -// Relation 14 (RDB$FUNCTIONS) - - const USHORT f_fun_name = 0; - const USHORT f_fun_type = 1; - const USHORT f_fun_qname = 2; - const USHORT f_fun_desc = 3; - const USHORT f_fun_module = 4; - const USHORT f_fun_entry = 5; - const USHORT f_fun_ret_arg = 6; - const USHORT f_fun_sys_flag = 7; - const USHORT f_fun_engine_name = 8; - const USHORT f_fun_pkg_name = 9; - const USHORT f_fun_private_flag = 10; - const USHORT f_fun_source = 11; - const USHORT f_fun_id = 12; - const USHORT f_fun_blr = 13; - const USHORT f_fun_valid_blr = 14; - const USHORT f_fun_debug_info = 15; - const USHORT f_fun_class = 16; - const USHORT f_fun_owner = 17; - const USHORT f_fun_legacy_flag = 18; - const USHORT f_fun_deterministic_flag = 19; - const USHORT f_fun_sql_security = 20; - - -// Relation 15 (RDB$FUNCTION_ARGUMENTS) - - const USHORT f_arg_fun_name = 0; - const USHORT f_arg_pos = 1; - const USHORT f_arg_mech = 2; - const USHORT f_arg_type = 3; - const USHORT f_arg_scale = 4; - const USHORT f_arg_length = 5; - const USHORT f_arg_sub_type = 6; - const USHORT f_arg_charset_id = 7; - const USHORT f_arg_precision = 8; - const USHORT f_arg_char_length = 9; - const USHORT f_arg_pkg_name = 10; - const USHORT f_arg_name = 11; - const USHORT f_arg_sname = 12; - const USHORT f_arg_default = 13; - const USHORT f_arg_dsource = 14; - const USHORT f_arg_coll_id = 15; - const USHORT f_arg_null_flag = 16; - const USHORT f_arg_arg_mech = 17; - const USHORT f_arg_fname = 18; - const USHORT f_arg_rname = 19; - const USHORT f_arg_sys_flag = 20; - const USHORT f_arg_desc = 21; - - -// Relation 16 (RDB$FILTERS) - - const USHORT f_flt_name = 0; - const USHORT f_flt_desc = 1; - const USHORT f_flt_module = 2; - const USHORT f_flt_entry = 3; - const USHORT f_flt_input = 4; - const USHORT f_flt_output = 5; - const USHORT f_flt_sys_flag = 6; - const USHORT f_flt_class = 7; - const USHORT f_flt_owner = 8; - - -// Relation 17 (RDB$TRIGGER_MESSAGES) - - const USHORT f_msg_trigger = 0; - const USHORT f_msg_number = 1; - const USHORT f_msg_msg = 2; - - -// Relation 18 (RDB$USER_PRIVILEGES) - - const USHORT f_prv_user = 0; - const USHORT f_prv_grantor = 1; - const USHORT f_prv_priv = 2; - const USHORT f_prv_grant = 3; - const USHORT f_prv_rname = 4; - const USHORT f_prv_fname = 5; - const USHORT f_prv_u_type = 6; - const USHORT f_prv_o_type = 7; - - -// Relation 19 (RDB$TRANSACTIONS) - - const USHORT f_trn_id = 0; - const USHORT f_trn_state = 1; - const USHORT f_trn_time = 2; - const USHORT f_trn_desc = 3; - - -// Relation 20 (RDB$GENERATORS) - - const USHORT f_gen_name = 0; - const USHORT f_gen_id = 1; - const USHORT f_gen_sys_flag = 2; - const USHORT f_gen_desc = 3; - const USHORT f_gen_class = 4; - const USHORT f_gen_owner = 5; - const USHORT f_gen_init_val = 6; - const USHORT f_gen_increment = 7; - - -// Relation 21 (RDB$FIELD_DIMENSIONS) - - const USHORT f_dims_fname = 0; - const USHORT f_dims_dim = 1; - const USHORT f_dims_lower = 2; - const USHORT f_dims_upper = 3; - - -// Relation 22 (RDB$RELATION_CONSTRAINTS) - - const USHORT f_rcon_cname = 0; - const USHORT f_rcon_ctype = 1; - const USHORT f_rcon_rname = 2; - const USHORT f_rcon_dfr = 3; - const USHORT f_rcon_idfr = 4; - const USHORT f_rcon_iname = 5; - - -// Relation 23 (RDB$REF_CONSTRAINTS) - - const USHORT f_refc_cname = 0; - const USHORT f_refc_uq = 1; - const USHORT f_refc_match = 2; - const USHORT f_refc_upd_rul = 3; - const USHORT f_refc_del_rul = 4; - - -// Relation 24 (RDB$CHECK_CONSTRAINTS) - - const USHORT f_ccon_cname = 0; - const USHORT f_ccon_tname = 1; - - -// Relation 25 (RDB$LOG_FILES) - - const USHORT f_log_name = 0; - const USHORT f_log_seq = 1; - const USHORT f_log_length = 2; - const USHORT f_log_partitions = 3; - const USHORT f_log_p_offset = 4; - const USHORT f_log_flags = 5; - - -// Relation 26 (RDB$PROCEDURES) - - const USHORT f_prc_name = 0; - const USHORT f_prc_id = 1; - const USHORT f_prc_inputs = 2; - const USHORT f_prc_outputs = 3; - const USHORT f_prc_desc = 4; - const USHORT f_prc_source = 5; - const USHORT f_prc_blr = 6; - const USHORT f_prc_class = 7; - const USHORT f_prc_owner = 8; - const USHORT f_prc_runtime = 9; - const USHORT f_prc_sys_flag = 10; - const USHORT f_prc_type = 11; - const USHORT f_prc_valid_blr = 12; - const USHORT f_prc_debug_info = 13; - const USHORT f_prc_engine_name = 14; - const USHORT f_prc_entry = 15; - const USHORT f_prc_pkg_name = 16; - const USHORT f_prc_private_flag = 17; - const USHORT f_prc_sql_security = 18; - - -// Relation 27 (RDB$PROCEDURE_PARAMETERS) - - const USHORT f_prm_name = 0; - const USHORT f_prm_procedure = 1; - const USHORT f_prm_number = 2; - const USHORT f_prm_type = 3; - const USHORT f_prm_sname = 4; - const USHORT f_prm_desc = 5; - const USHORT f_prm_sys_flag = 6; - const USHORT f_prm_default = 7; - const USHORT f_prm_dsource = 8; - const USHORT f_prm_coll_id = 9; - const USHORT f_prm_null_flag = 10; - const USHORT f_prm_mech = 11; - const USHORT f_prm_fname = 12; - const USHORT f_prm_rname = 13; - const USHORT f_prm_pkg_name = 14; - - -// Relation 28 (RDB$CHARACTER_SETS) - - const USHORT f_cs_cs_name = 0; - const USHORT f_cs_form_of_use = 1; - const USHORT f_cs_num_chars = 2; - const USHORT f_cs_def_collate = 3; - const USHORT f_cs_id = 4; - const USHORT f_cs_sys_flag = 5; - const USHORT f_cs_desc = 6; - const USHORT f_cs_fun_name = 7; - const USHORT f_cs_bytes_char = 8; - const USHORT f_cs_class = 9; - const USHORT f_cs_owner = 10; - - -// Relation 29 (RDB$COLLATIONS) - - const USHORT f_coll_name = 0; - const USHORT f_coll_id = 1; - const USHORT f_coll_cs_id = 2; - const USHORT f_coll_attr = 3; - const USHORT f_coll_sys_flag = 4; - const USHORT f_coll_desc = 5; - const USHORT f_coll_fun_name = 6; - const USHORT f_coll_base_collation_name = 7; - const USHORT f_coll_specific_attr = 8; - const USHORT f_coll_class = 9; - const USHORT f_coll_owner = 10; - - -// Relation 30 (RDB$EXCEPTIONS) - - const USHORT f_xcp_name = 0; - const USHORT f_xcp_number = 1; - const USHORT f_xcp_msg = 2; - const USHORT f_xcp_desc = 3; - const USHORT f_xcp_sys_flag = 4; - const USHORT f_xcp_class = 5; - const USHORT f_xcp_owner = 6; - - -// Relation 31 (RDB$ROLES) - - const USHORT f_rol_name = 0; - const USHORT f_rol_owner = 1; - const USHORT f_rol_desc = 2; - const USHORT f_rol_sys_flag = 3; - const USHORT f_rol_class = 4; - const USHORT f_rol_sys_priv = 5; - - -// Relation 32 (RDB$BACKUP_HISTORY) - - const USHORT f_backup_id = 0; - const USHORT f_backup_time = 1; - const USHORT f_backup_level = 2; - const USHORT f_backup_guid = 3; - const USHORT f_backup_scn = 4; - const USHORT f_backup_name = 5; - - -// Relation 33 (MON$DATABASE) - - const USHORT f_mon_db_name = 0; - const USHORT f_mon_db_page_size = 1; - const USHORT f_mon_db_ods_major = 2; - const USHORT f_mon_db_ods_minor = 3; - const USHORT f_mon_db_oit = 4; - const USHORT f_mon_db_oat = 5; - const USHORT f_mon_db_ost = 6; - const USHORT f_mon_db_nt = 7; - const USHORT f_mon_db_page_bufs = 8; - const USHORT f_mon_db_dialect = 9; - const USHORT f_mon_db_shut_mode = 10; - const USHORT f_mon_db_sweep_int = 11; - const USHORT f_mon_db_read_only = 12; - const USHORT f_mon_db_forced_writes = 13; - const USHORT f_mon_db_res_space = 14; - const USHORT f_mon_db_created = 15; - const USHORT f_mon_db_pages = 16; - const USHORT f_mon_db_stat_id = 17; - const USHORT f_mon_db_backup_state = 18; - const USHORT f_mon_db_crypt_page = 19; - const USHORT f_mon_db_owner = 20; - const USHORT f_mon_db_secdb = 21; - const USHORT f_mon_db_crypt_state = 22; - - -// Relation 34 (MON$ATTACHMENTS) - - const USHORT f_mon_att_id = 0; - const USHORT f_mon_att_server_pid = 1; - const USHORT f_mon_att_state = 2; - const USHORT f_mon_att_name = 3; - const USHORT f_mon_att_user = 4; - const USHORT f_mon_att_role = 5; - const USHORT f_mon_att_remote_proto = 6; - const USHORT f_mon_att_remote_addr = 7; - const USHORT f_mon_att_remote_pid = 8; - const USHORT f_mon_att_charset_id = 9; - const USHORT f_mon_att_timestamp = 10; - const USHORT f_mon_att_gc = 11; - const USHORT f_mon_att_remote_process = 12; - const USHORT f_mon_att_stat_id = 13; - const USHORT f_mon_att_client_version = 14; - const USHORT f_mon_att_remote_version = 15; - const USHORT f_mon_att_remote_host = 16; - const USHORT f_mon_att_remote_os_user = 17; - const USHORT f_mon_att_auth_method = 18; - const USHORT f_mon_att_sys_flag = 19; - const USHORT f_mon_att_idle_timeout = 20; - const USHORT f_mon_att_idle_timer = 21; - const USHORT f_mon_att_stmt_timeout = 22; - const USHORT f_mon_att_wire_compressed = 23; - const USHORT f_mon_att_wire_encrypted = 24; - const USHORT f_mon_att_remote_crypt = 25; - - -// Relation 35 (MON$TRANSACTIONS) - - const USHORT f_mon_tra_id = 0; - const USHORT f_mon_tra_att_id = 1; - const USHORT f_mon_tra_state = 2; - const USHORT f_mon_tra_timestamp = 3; - const USHORT f_mon_tra_top = 4; - const USHORT f_mon_tra_oit = 5; - const USHORT f_mon_tra_oat = 6; - const USHORT f_mon_tra_iso_mode = 7; - const USHORT f_mon_tra_lock_timeout = 8; - const USHORT f_mon_tra_read_only = 9; - const USHORT f_mon_tra_auto_commit = 10; - const USHORT f_mon_tra_auto_undo = 11; - const USHORT f_mon_tra_stat_id = 12; - - -// Relation 36 (MON$STATEMENTS) - - const USHORT f_mon_stmt_id = 0; - const USHORT f_mon_stmt_att_id = 1; - const USHORT f_mon_stmt_tra_id = 2; - const USHORT f_mon_stmt_state = 3; - const USHORT f_mon_stmt_timestamp = 4; - const USHORT f_mon_stmt_sql_text = 5; - const USHORT f_mon_stmt_stat_id = 6; - const USHORT f_mon_stmt_expl_plan = 7; - const USHORT f_mon_stmt_timeout = 8; - const USHORT f_mon_stmt_timer = 9; - - -// Relation 37 (MON$CALL_STACK) - - const USHORT f_mon_call_id = 0; - const USHORT f_mon_call_stmt_id = 1; - const USHORT f_mon_call_caller_id = 2; - const USHORT f_mon_call_name = 3; - const USHORT f_mon_call_type = 4; - const USHORT f_mon_call_timestamp = 5; - const USHORT f_mon_call_src_line = 6; - const USHORT f_mon_call_src_column = 7; - const USHORT f_mon_call_stat_id = 8; - const USHORT f_mon_call_pkg_name = 9; - - -// Relation 38 (MON$IO_STATS) - - const USHORT f_mon_io_stat_id = 0; - const USHORT f_mon_io_stat_group = 1; - const USHORT f_mon_io_page_reads = 2; - const USHORT f_mon_io_page_writes = 3; - const USHORT f_mon_io_page_fetches = 4; - const USHORT f_mon_io_page_marks = 5; - - -// Relation 39 (MON$RECORD_STATS) - - const USHORT f_mon_rec_stat_id = 0; - const USHORT f_mon_rec_stat_group = 1; - const USHORT f_mon_rec_seq_reads = 2; - const USHORT f_mon_rec_idx_reads = 3; - const USHORT f_mon_rec_inserts = 4; - const USHORT f_mon_rec_updates = 5; - const USHORT f_mon_rec_deletes = 6; - const USHORT f_mon_rec_backouts = 7; - const USHORT f_mon_rec_purges = 8; - const USHORT f_mon_rec_expunges = 9; - const USHORT f_mon_rec_locks = 10; - const USHORT f_mon_rec_waits = 11; - const USHORT f_mon_rec_conflicts = 12; - const USHORT f_mon_rec_bkver_reads = 13; - const USHORT f_mon_rec_frg_reads = 14; - const USHORT f_mon_rec_rpt_reads = 15; - const USHORT f_mon_rec_imgc = 16; - - -// Relation 40 (MON$CONTEXT_VARIABLES) - - const USHORT f_mon_ctx_var_att_id = 0; - const USHORT f_mon_ctx_var_tra_id = 1; - const USHORT f_mon_ctx_var_name = 2; - const USHORT f_mon_ctx_var_value = 3; - - -// Relation 41 (MON$MEMORY_USAGE) - - const USHORT f_mon_mem_stat_id = 0; - const USHORT f_mon_mem_stat_group = 1; - const USHORT f_mon_mem_cur_used = 2; - const USHORT f_mon_mem_cur_alloc = 3; - const USHORT f_mon_mem_max_used = 4; - const USHORT f_mon_mem_max_alloc = 5; - - -// Relation 42 (RDB$PACKAGES) - - const USHORT f_pkg_name = 0; - const USHORT f_pkg_header_source = 1; - const USHORT f_pkg_body_source = 2; - const USHORT f_pkg_valid_body_flag = 3; - const USHORT f_pkg_class = 4; - const USHORT f_pkg_owner = 5; - const USHORT f_pkg_sys_flag = 6; - const USHORT f_pkg_desc = 7; - const USHORT f_pkg_sql_security = 8; - - -// Relation 43 (SEC$USERS) - - const USHORT f_sec_user_name = 0; - const USHORT f_sec_first_name = 1; - const USHORT f_sec_middle_name = 2; - const USHORT f_sec_last_name = 3; - const USHORT f_sec_active = 4; - const USHORT f_sec_admin = 5; - const USHORT f_sec_comment = 6; - const USHORT f_sec_plugin = 7; - - -// Relation 44 (SEC$USER_ATTRIBUTES) - - const USHORT f_sec_attr_user = 0; - const USHORT f_sec_attr_key = 1; - const USHORT f_sec_attr_value = 2; - const USHORT f_sec_attr_plugin = 3; - - -// Relation 45 (RDB$AUTH_MAPPING) - - const USHORT f_map_name = 0; - const USHORT f_map_using = 1; - const USHORT f_map_plugin = 2; - const USHORT f_map_db = 3; - const USHORT f_map_from_type = 4; - const USHORT f_map_from = 5; - const USHORT f_map_to_type = 6; - const USHORT f_map_to = 7; - const USHORT f_map_sys_flag = 8; - const USHORT f_map_desc = 9; - - -// Relation 46 (SEC$GLOBAL_AUTH_MAPPING) - - const USHORT f_sec_map_name = 0; - const USHORT f_sec_map_using = 1; - const USHORT f_sec_map_plugin = 2; - const USHORT f_sec_map_db = 3; - const USHORT f_sec_map_from_type = 4; - const USHORT f_sec_map_from = 5; - const USHORT f_sec_map_to_type = 6; - const USHORT f_sec_map_to = 7; - - -// Relation 47 (RDB$DB_CREATORS) - - const USHORT f_crt_user = 0; - const USHORT f_crt_u_type = 1; - - -// Relation 48 (SEC$DB_CREATORS) - - const USHORT f_sec_crt_user = 0; - const USHORT f_sec_crt_u_type = 1; - - -// Relation 49 (MON$TABLE_STATS) - - const USHORT f_mon_tab_stat_id = 0; - const USHORT f_mon_tab_stat_group = 1; - const USHORT f_mon_tab_name = 2; - const USHORT f_mon_tab_rec_stat_id = 3; - - -// Relation 50 (RDB$TIME_ZONES) - - const USHORT f_tz_id = 0; - const USHORT f_tz_name = 1; - - diff --git a/src/jrd/DbCreators.cpp b/src/jrd/DbCreators.cpp index 113678912f..ead6f27708 100644 --- a/src/jrd/DbCreators.cpp +++ b/src/jrd/DbCreators.cpp @@ -49,7 +49,7 @@ #include "../jrd/tra.h" #include "../jrd/ini.h" #include "../jrd/status.h" -#include "gen/ids.h" +#include "../jrd/ids.h" #define DBC_DEBUG(A) diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp index 781052398c..a0a9e04da7 100644 --- a/src/jrd/Mapping.cpp +++ b/src/jrd/Mapping.cpp @@ -46,7 +46,7 @@ #include "../jrd/tra.h" #include "../jrd/ini.h" #include "../jrd/status.h" -#include "gen/ids.h" +#include "../jrd/ids.h" #ifdef WIN_NT #include diff --git a/src/jrd/TimeZone.cpp b/src/jrd/TimeZone.cpp index d89c092473..20565c30f0 100644 --- a/src/jrd/TimeZone.cpp +++ b/src/jrd/TimeZone.cpp @@ -25,7 +25,7 @@ #include "../jrd/Record.h" #include "../jrd/ini.h" #include "../jrd/tra.h" -#include "gen/ids.h" +#include "../jrd/ids.h" using namespace Jrd; using namespace Firebird; diff --git a/src/jrd/UserManagement.cpp b/src/jrd/UserManagement.cpp index ccfae63f2d..c1ed05501c 100644 --- a/src/jrd/UserManagement.cpp +++ b/src/jrd/UserManagement.cpp @@ -30,7 +30,7 @@ #include "../common/security.h" #include "../jrd/met_proto.h" #include "../jrd/ini.h" -#include "gen/ids.h" +#include "../jrd/ids.h" using namespace Jrd; using namespace Firebird; diff --git a/src/jrd/ids.h b/src/jrd/ids.h new file mode 100644 index 0000000000..5d240d311d --- /dev/null +++ b/src/jrd/ids.h @@ -0,0 +1,89 @@ +/* + * PROGRAM: JRD Access Method + * MODULE: ids.h + * DESCRIPTION: System relation field numbers + * + * The contents of this file are subject to the Interbase Public + * License Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy + * of the License at http://www.Inprise.com/IPL.html + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code was created by Inprise Corporation + * and its predecessors. Portions created by Inprise Corporation are + * Copyright (C) Inprise Corporation. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#define RELATION(...) enum : USHORT { +#define FIELD(field_id, ...) field_id, +#define END_RELATION }; + +#include "relations.h" + +#undef RELATION +#undef FIELD +#undef END_RELATION + + +// Because it is ODS-related header, an additional check +// to ensure compatibility: position of one field for each table is checked. +// This field don't have to be the last, any one is good. + + static_assert(f_pag_type == 3, "Wrong field id"); + static_assert(f_dat_sql_security == 5, "Wrong field id"); + static_assert(f_fld_owner == 29, "Wrong field id"); + static_assert(f_seg_statistics == 3, "Wrong field id"); + static_assert(f_idx_statistics == 12, "Wrong field id"); + static_assert(f_rfr_identity_type == 20, "Wrong field id"); + static_assert(f_rel_sql_security == 17, "Wrong field id"); + static_assert(f_vrl_pkg_name == 5, "Wrong field id"); + static_assert(f_fmt_desc == 2, "Wrong field id"); + static_assert(f_cls_desc == 2, "Wrong field id"); + static_assert(f_file_shad_num == 5, "Wrong field id"); + static_assert(f_typ_sys_flag == 4, "Wrong field id"); + static_assert(f_trg_sql_security == 14, "Wrong field id"); + static_assert(f_dpd_pkg_name == 5, "Wrong field id"); + static_assert(f_fun_sql_security == 20, "Wrong field id"); + static_assert(f_arg_desc == 21, "Wrong field id"); + static_assert(f_flt_owner == 8, "Wrong field id"); + static_assert(f_msg_msg == 2, "Wrong field id"); + static_assert(f_prv_o_type == 7, "Wrong field id"); + static_assert(f_trn_desc == 3, "Wrong field id"); + static_assert(f_gen_increment == 7, "Wrong field id"); + static_assert(f_dims_upper == 3, "Wrong field id"); + static_assert(f_rcon_iname == 5, "Wrong field id"); + static_assert(f_refc_del_rul == 4, "Wrong field id"); + static_assert(f_ccon_tname == 1, "Wrong field id"); + static_assert(f_log_flags == 5, "Wrong field id"); + static_assert(f_prc_sql_security == 18, "Wrong field id"); + static_assert(f_prm_pkg_name == 14, "Wrong field id"); + static_assert(f_cs_owner == 10, "Wrong field id"); + static_assert(f_coll_owner == 10, "Wrong field id"); + static_assert(f_xcp_owner == 6, "Wrong field id"); + static_assert(f_rol_sys_priv == 5, "Wrong field id"); + static_assert(f_backup_name == 5, "Wrong field id"); + static_assert(f_mon_db_crypt_state == 22, "Wrong field id"); + static_assert(f_mon_att_remote_crypt == 25, "Wrong field id"); + static_assert(f_mon_tra_stat_id == 12, "Wrong field id"); + static_assert(f_mon_stmt_timer == 9, "Wrong field id"); + static_assert(f_mon_call_pkg_name == 9, "Wrong field id"); + static_assert(f_mon_io_page_marks == 5, "Wrong field id"); + static_assert(f_mon_rec_imgc == 16, "Wrong field id"); + static_assert(f_mon_ctx_var_value == 3, "Wrong field id"); + static_assert(f_mon_mem_max_alloc == 5, "Wrong field id"); + static_assert(f_pkg_sql_security == 8, "Wrong field id"); + static_assert(f_sec_plugin == 7, "Wrong field id"); + static_assert(f_sec_attr_plugin == 3, "Wrong field id"); + static_assert(f_map_desc == 9, "Wrong field id"); + static_assert(f_sec_map_to == 7, "Wrong field id"); + static_assert(f_crt_u_type == 1, "Wrong field id"); + static_assert(f_sec_crt_u_type == 1, "Wrong field id"); + static_assert(f_mon_tab_rec_stat_id == 3, "Wrong field id"); + static_assert(f_tz_name == 1, "Wrong field id"); diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index e501980986..84ddfe306e 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -29,7 +29,7 @@ #include "../jrd/val.h" #include "../jrd/ods.h" #include "../jrd/btr.h" -#include "gen/ids.h" +#include "../jrd/ids.h" #include "../jrd/intl.h" #include "../jrd/tra.h" #include "../jrd/trig.h" diff --git a/src/jrd/replication/Applier.cpp b/src/jrd/replication/Applier.cpp index a326481dc2..1fd6ef3c3e 100644 --- a/src/jrd/replication/Applier.cpp +++ b/src/jrd/replication/Applier.cpp @@ -21,7 +21,7 @@ */ #include "firebird.h" -#include "ids.h" +#include "../ids.h" #include "../jrd/align.h" #include "../jrd/jrd.h" #include "../jrd/blb.h" diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 6c7ff8e06e..e7b1a5d114 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -48,7 +48,7 @@ #include "../jrd/val.h" #include "../jrd/req.h" #include "../jrd/tra.h" -#include "gen/ids.h" +#include "../jrd/ids.h" #include "../jrd/lck.h" #include "../jrd/lls.h" #include "../jrd/scl.h" diff --git a/src/misc/ids.m b/src/misc/ids.m deleted file mode 100644 index 899d658abd..0000000000 --- a/src/misc/ids.m +++ /dev/null @@ -1,30 +0,0 @@ -divert(-1) -/* - * The contents of this file are subject to the Interbase Public - * License Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy - * of the License at http://www.Inprise.com/IPL.html - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code was created by Inprise Corporation - * and its predecessors. Portions created by Inprise Corporation are - * Copyright (C) Inprise Corporation. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - */ - -changequote([,]) - -define(RELATION, [define([N], 0)]) -define(FIELD, [[const USHORT ] $1 [=] N[;]define([N], incr(N)) -dnl]) -define(END_RELATION, ) -define(FIELD_ODS8, ) - -divert -include(../src/jrd/relations.h) From 4b6eaa57c3f925468b64ca91b95511cd58e2676e Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 21 Jan 2020 12:57:31 -0300 Subject: [PATCH 31/39] Move tzdata to extern/icu. --- .github/workflows/tzdata-update.yml | 6 +++--- builds/posix/Makefile.in | 4 ++-- builds/win32/make_icu.bat | 2 +- extern/icu/Readme.txt | 6 +++++- {tzdata => extern/icu/tzdata}/be.zip | Bin {tzdata => extern/icu/tzdata}/le.zip | Bin {tzdata => extern/icu/tzdata}/update.sh | 0 {tzdata => extern/icu/tzdata}/version.txt | 0 8 files changed, 11 insertions(+), 7 deletions(-) rename {tzdata => extern/icu/tzdata}/be.zip (100%) rename {tzdata => extern/icu/tzdata}/le.zip (100%) rename {tzdata => extern/icu/tzdata}/update.sh (100%) rename {tzdata => extern/icu/tzdata}/version.txt (100%) diff --git a/.github/workflows/tzdata-update.yml b/.github/workflows/tzdata-update.yml index 7af28a4b59..08842f048e 100644 --- a/.github/workflows/tzdata-update.yml +++ b/.github/workflows/tzdata-update.yml @@ -19,13 +19,13 @@ jobs: VERSION=`ls /tmp/icu-checkout/tzdata/icunew/ -r1a |head -1` echo Last version: $VERSION - if [ "$VERSION" == "`cat tzdata/version.txt`" ] + if [ "$VERSION" == "`cat extern/icu/tzdata/version.txt`" ] then exit fi - echo $VERSION > tzdata/version.txt - tzdata/update.sh + echo $VERSION > extern/icu/tzdata/version.txt + extern/icu/tzdata/update.sh - name: Create Pull Request uses: peter-evans/create-pull-request@v2 diff --git a/builds/posix/Makefile.in b/builds/posix/Makefile.in index 3f05cd22ac..c194682fc3 100644 --- a/builds/posix/Makefile.in +++ b/builds/posix/Makefile.in @@ -624,8 +624,8 @@ $(FIREBIRD_MSG): $(BUILD_FILE) msg.timestamp tzdata: $(FIREBIRD)/tzdata # FIXME: For big-endian, be.zip must be used. -$(FIREBIRD)/tzdata: $(ROOT)/tzdata/le.zip - unzip -o $(ROOT)/tzdata/le.zip -d $(FIREBIRD)/tzdata +$(FIREBIRD)/tzdata: $(ROOT)/extern/icu/tzdata/le.zip + unzip -o $(ROOT)/extern/icu/tzdata/le.zip -d $(FIREBIRD)/tzdata $(BUILD_FILE): $(BUILD_Objects) $(COMMON_LIB) $(EXE_LINK) $(EXE_LINK_OPTIONS) $(LSB_UNDEF) $^ -o $@ $(FIREBIRD_LIBRARY_LINK) $(LINK_LIBS) $(call LINK_DARWIN_RPATH,..) diff --git a/builds/win32/make_icu.bat b/builds/win32/make_icu.bat index 7eaa3aaf0a..ced0139464 100644 --- a/builds/win32/make_icu.bat +++ b/builds/win32/make_icu.bat @@ -15,7 +15,7 @@ if errorlevel 1 call :ERROR build failed - see make_icu_%FB_TARGET_PLATFORM%.log @echo Extracting tzdata mkdir %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata -call zipjs.bat unzip -source "%FB_LONG_ROOT_PATH%\tzdata\le.zip" -destination %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata -keep yes +call zipjs.bat unzip -source "%FB_LONG_ROOT_PATH%\extern\icu\tzdata\le.zip" -destination %FB_ROOT_PATH%\temp\%FB_OBJ_DIR%\firebird\tzdata -keep yes @goto :EOF diff --git a/extern/icu/Readme.txt b/extern/icu/Readme.txt index 58ad881a06..990fa71721 100644 --- a/extern/icu/Readme.txt +++ b/extern/icu/Readme.txt @@ -2,10 +2,14 @@ icu.exe is a self-extract pre-built (by us) IBM ICU 63.1 library. The sources was downloaded from http://site.icu-project.org/download. -The simple fix for bug ICU-20302 (Windows 7: timezone detection on Windows +The simple fix for bug ICU-20302 (Windows 7: timezone detection on Windows is broken) is applyed, see: https://unicode-org.atlassian.net/browse/ICU-20302 https://github.com/unicode-org/icu/pull/315 The build was done using VS 2017 (15.9). + +--- + +tzdata is automatically updated (pull request created) by GitHub Actions tzdata-update.yml. diff --git a/tzdata/be.zip b/extern/icu/tzdata/be.zip similarity index 100% rename from tzdata/be.zip rename to extern/icu/tzdata/be.zip diff --git a/tzdata/le.zip b/extern/icu/tzdata/le.zip similarity index 100% rename from tzdata/le.zip rename to extern/icu/tzdata/le.zip diff --git a/tzdata/update.sh b/extern/icu/tzdata/update.sh similarity index 100% rename from tzdata/update.sh rename to extern/icu/tzdata/update.sh diff --git a/tzdata/version.txt b/extern/icu/tzdata/version.txt similarity index 100% rename from tzdata/version.txt rename to extern/icu/tzdata/version.txt From 6fa1fffbaa6b68e2c735d57e312e416c6b23459c Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Wed, 22 Jan 2020 00:07:05 +0000 Subject: [PATCH 32/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 35093fe8b7..2e838a0e0f 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1737 + FORMAL BUILD NUMBER:1739 */ -#define PRODUCT_VER_STRING "4.0.0.1737" -#define FILE_VER_STRING "WI-T4.0.0.1737" -#define LICENSE_VER_STRING "WI-T4.0.0.1737" -#define FILE_VER_NUMBER 4, 0, 0, 1737 +#define PRODUCT_VER_STRING "4.0.0.1739" +#define FILE_VER_STRING "WI-T4.0.0.1739" +#define LICENSE_VER_STRING "WI-T4.0.0.1739" +#define FILE_VER_NUMBER 4, 0, 0, 1739 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1737" +#define FB_BUILD_NO "1739" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index 47d4f35077..b8edfc811e 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1737 +BuildNum=1739 NowAt=`pwd` cd `dirname $0` From 675365675425d416da1757b56f2cac78820a4599 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Tue, 21 Jan 2020 22:09:17 -0300 Subject: [PATCH 33/39] Fixed CORE-6236 - RDB$TIME_ZONE_UTIL package has wrong privilege for PUBLIC. --- src/jrd/ini.epp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 84ddfe306e..0a6e185121 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -71,9 +71,9 @@ const int FB_MAX_ACL_SIZE = 4096; static void add_index_set(thread_db*); -static void add_security_to_sys_obj(thread_db*, AutoRequest&, AutoRequest&, AutoRequest&, +static void add_security_to_sys_obj(thread_db*, AutoRequest&, AutoRequest&, AutoRequest&, const MetaName&, USHORT, const MetaName&, USHORT = 0, const UCHAR* = NULL); -static void add_security_class(thread_db* tdbb, AutoRequest&, const MetaName& class_name, +static void add_security_class(thread_db* tdbb, AutoRequest&, const MetaName& class_name, USHORT acl_length, const UCHAR* acl); static void add_security_to_sys_rel(thread_db*, AutoRequest&, AutoRequest&, AutoRequest&, const MetaName&, const TEXT*, const USHORT, const UCHAR*); @@ -411,9 +411,12 @@ void INI_format(const char* owner, const char* charset) const UCHAR NON_REL_OWNER_ACL[] = {ACL_priv_list, priv_control, priv_alter, priv_drop, priv_usage, ACL_end}; - const UCHAR NON_REL_PUBLIC_ACL[] = + const UCHAR NON_REL_PUBLIC_USAGE_ACL[] = {ACL_priv_list, priv_usage, ACL_end}; + const UCHAR PKG_PUBLIC_EXECUTE_ACL[] = + {ACL_priv_list, priv_execute, ACL_end}; + UCHAR buffer[FB_MAX_ACL_SIZE]; UCHAR* acl = buffer; *acl++ = ACL_version; @@ -431,8 +434,11 @@ void INI_format(const char* owner, const char* charset) *acl++ = ACL_id_list; *acl++ = ACL_end; - memcpy(acl, NON_REL_PUBLIC_ACL, sizeof(NON_REL_PUBLIC_ACL)); - acl += sizeof(NON_REL_PUBLIC_ACL); + + UCHAR* aclPublicStart = acl; + + memcpy(acl, NON_REL_PUBLIC_USAGE_ACL, sizeof(NON_REL_PUBLIC_USAGE_ACL)); + acl += sizeof(NON_REL_PUBLIC_USAGE_ACL); *acl++ = ACL_end; // Put an extra terminator to avoid scl.epp:walk_acl() missing the end. USHORT length = acl - buffer; @@ -471,13 +477,21 @@ void INI_format(const char* owner, const char* charset) add_security_to_sys_obj(tdbb, reqAddSC, reqModObjSC, reqInsUserPriv, ownerName, obj_collation, collation->name, length, buffer); } + // Must be last! + acl = aclPublicStart; + memcpy(acl, PKG_PUBLIC_EXECUTE_ACL, sizeof(PKG_PUBLIC_EXECUTE_ACL)); + acl += sizeof(PKG_PUBLIC_EXECUTE_ACL); + *acl++ = ACL_end; // Put an extra terminator to avoid scl.epp:walk_acl() missing the end. + length = acl - buffer; + reqModObjSC.reset(); for (auto& systemPackage : SystemPackage::get()) { if (systemPackage.odsVersion > ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_version)) continue; - add_security_to_sys_obj(tdbb, reqAddSC, reqModObjSC, reqInsUserPriv, ownerName, obj_package_header, systemPackage.name, length, buffer); + add_security_to_sys_obj(tdbb, reqAddSC, reqModObjSC, reqInsUserPriv, ownerName, + obj_package_header, systemPackage.name, length, buffer); } } @@ -1091,8 +1105,8 @@ static void add_security_to_sys_rel(thread_db* tdbb, // Add security to system objects. static void add_security_to_sys_obj(thread_db* tdbb, - AutoRequest& reqAddSC, - AutoRequest& reqModObjSC, + AutoRequest& reqAddSC, + AutoRequest& reqModObjSC, AutoRequest& reqInsUserPriv, const MetaName& user_name, USHORT obj_type, From e6d079293459b6939220a9d86ca396d29a09a028 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Thu, 23 Jan 2020 00:04:37 +0000 Subject: [PATCH 34/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 2e838a0e0f..c6fc0a83f9 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1739 + FORMAL BUILD NUMBER:1740 */ -#define PRODUCT_VER_STRING "4.0.0.1739" -#define FILE_VER_STRING "WI-T4.0.0.1739" -#define LICENSE_VER_STRING "WI-T4.0.0.1739" -#define FILE_VER_NUMBER 4, 0, 0, 1739 +#define PRODUCT_VER_STRING "4.0.0.1740" +#define FILE_VER_STRING "WI-T4.0.0.1740" +#define LICENSE_VER_STRING "WI-T4.0.0.1740" +#define FILE_VER_NUMBER 4, 0, 0, 1740 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1739" +#define FB_BUILD_NO "1740" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index b8edfc811e..c997c6d447 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1739 +BuildNum=1740 NowAt=`pwd` cd `dirname $0` From e93a729892fdb2d8839ebfdbb6a76662fde1b363 Mon Sep 17 00:00:00 2001 From: Dmitry Yemanov Date: Thu, 23 Jan 2020 12:18:44 +0300 Subject: [PATCH 35/39] Postfix for CORE-6236 (RDB package has wrong privilege for PUBLIC) --- src/jrd/ini.epp | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/jrd/ini.epp b/src/jrd/ini.epp index 0a6e185121..fb8cf5b87c 100644 --- a/src/jrd/ini.epp +++ b/src/jrd/ini.epp @@ -1123,6 +1123,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, add_security_class(tdbb, reqAddSC, security_class, acl_length, acl); + bool needsUsagePrivileges = false, needsExecPrivileges = false; + if (obj_type == obj_field) { FOR(REQUEST_HANDLE reqModObjSC) FLD IN RDB$FIELDS @@ -1132,6 +1134,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, FLD.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), FLD.RDB$SECURITY_CLASS); END_MODIFY + + needsUsagePrivileges = true; } END_FOR } @@ -1144,6 +1148,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, CS.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), CS.RDB$SECURITY_CLASS); END_MODIFY + + needsUsagePrivileges = true; } END_FOR } @@ -1156,6 +1162,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, COLL.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), COLL.RDB$SECURITY_CLASS); END_MODIFY + + needsUsagePrivileges = true; } END_FOR } @@ -1168,6 +1176,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, XCP.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), XCP.RDB$SECURITY_CLASS); END_MODIFY + + needsUsagePrivileges = true; } END_FOR } @@ -1180,6 +1190,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, GEN.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), GEN.RDB$SECURITY_CLASS); END_MODIFY + + needsUsagePrivileges = true; } END_FOR } @@ -1192,6 +1204,8 @@ static void add_security_to_sys_obj(thread_db* tdbb, PKG.RDB$SECURITY_CLASS.NULL = FALSE; PAD(security_class.c_str(), PKG.RDB$SECURITY_CLASS); END_MODIFY + + needsExecPrivileges = true; } END_FOR } @@ -1209,18 +1223,29 @@ static void add_security_to_sys_obj(thread_db* tdbb, else fb_assert(false); - for (const char* p = USAGE_PRIVILEGES; *p; ++p) + const char* const privileges = + needsUsagePrivileges ? USAGE_PRIVILEGES : + needsExecPrivileges ? EXEC_PRIVILEGES : + NULL; + + if (privileges) { - STORE(REQUEST_HANDLE reqInsUserPriv) PRIV IN RDB$USER_PRIVILEGES - PAD(user_name.c_str(), PRIV.RDB$USER); - PAD(obj_name.c_str(), PRIV.RDB$RELATION_NAME); - PRIV.RDB$PRIVILEGE[0] = *p; - PRIV.RDB$PRIVILEGE[1] = 0; - PRIV.RDB$GRANT_OPTION = WITH_GRANT_OPTION; - PRIV.RDB$USER_TYPE = obj_user; - PRIV.RDB$OBJECT_TYPE = obj_type; - PRIV.RDB$GRANTOR.NULL = TRUE; - END_STORE + fb_assert(user_name.hasData()); + fb_assert(obj_name.hasData()); + + for (const char* p = privileges; *p; ++p) + { + STORE(REQUEST_HANDLE reqInsUserPriv) PRIV IN RDB$USER_PRIVILEGES + PAD(user_name.c_str(), PRIV.RDB$USER); + PAD(obj_name.c_str(), PRIV.RDB$RELATION_NAME); + PRIV.RDB$PRIVILEGE[0] = *p; + PRIV.RDB$PRIVILEGE[1] = 0; + PRIV.RDB$GRANT_OPTION = WITH_GRANT_OPTION; + PRIV.RDB$USER_TYPE = obj_user; + PRIV.RDB$OBJECT_TYPE = obj_type; + PRIV.RDB$GRANTOR.NULL = TRUE; + END_STORE + } } } From 8060136b7a7e6a51f2881700fe89f6465b504526 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Fri, 24 Jan 2020 00:04:37 +0000 Subject: [PATCH 36/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index c6fc0a83f9..314846e07e 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1740 + FORMAL BUILD NUMBER:1741 */ -#define PRODUCT_VER_STRING "4.0.0.1740" -#define FILE_VER_STRING "WI-T4.0.0.1740" -#define LICENSE_VER_STRING "WI-T4.0.0.1740" -#define FILE_VER_NUMBER 4, 0, 0, 1740 +#define PRODUCT_VER_STRING "4.0.0.1741" +#define FILE_VER_STRING "WI-T4.0.0.1741" +#define LICENSE_VER_STRING "WI-T4.0.0.1741" +#define FILE_VER_NUMBER 4, 0, 0, 1741 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1740" +#define FB_BUILD_NO "1741" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index c997c6d447..e5bbbefbd5 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1740 +BuildNum=1741 NowAt=`pwd` cd `dirname $0` From 98efe88f11cb167633233565f74795ecaa927e19 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sun, 26 Jan 2020 12:23:42 -0300 Subject: [PATCH 37/39] Fixed CORE-6233 - Wrong dependencies of stored function on view after backup and restore. --- src/burp/restore.epp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/burp/restore.epp b/src/burp/restore.epp index 0cce0e69f0..267119b87c 100644 --- a/src/burp/restore.epp +++ b/src/burp/restore.epp @@ -4903,12 +4903,15 @@ bool get_function(BurpGlobals* tdgbl) bool existFlag = false; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + if (tdgbl->runtimeODS >= DB_VERSION_DDL12) { GDS_NAME function_name; bool securityClass = false; - STORE (REQUEST_HANDLE tdgbl->handles_get_function_req_handle1) + STORE (TRANSACTION_HANDLE local_trans + REQUEST_HANDLE tdgbl->handles_get_function_req_handle1) X IN RDB$FUNCTIONS X.RDB$DESCRIPTION.NULL = TRUE; X.RDB$ENGINE_NAME.NULL = TRUE; @@ -4959,12 +4962,12 @@ bool get_function(BurpGlobals* tdgbl) case att_function_description: X.RDB$DESCRIPTION.NULL = FALSE; - get_misc_blob (tdgbl, X.RDB$DESCRIPTION, false); + get_misc_blob (tdgbl, X.RDB$DESCRIPTION, true); break; case att_function_description2: X.RDB$DESCRIPTION.NULL = FALSE; - get_source_blob (tdgbl, X.RDB$DESCRIPTION, false); + get_source_blob (tdgbl, X.RDB$DESCRIPTION, true); break; case att_function_module_name: @@ -5024,7 +5027,7 @@ bool get_function(BurpGlobals* tdgbl) case att_function_blr: if (tdgbl->RESTORE_format >= 10) { - get_blr_blob(tdgbl, X.RDB$FUNCTION_BLR, false); + get_blr_blob(tdgbl, X.RDB$FUNCTION_BLR, true); X.RDB$FUNCTION_BLR.NULL = FALSE; } else @@ -5034,7 +5037,7 @@ bool get_function(BurpGlobals* tdgbl) case att_function_source: if (tdgbl->RESTORE_format >= 10) { - get_source_blob(tdgbl, X.RDB$FUNCTION_SOURCE, false); + get_source_blob(tdgbl, X.RDB$FUNCTION_SOURCE, true); X.RDB$FUNCTION_SOURCE.NULL = FALSE; } else @@ -5054,7 +5057,7 @@ bool get_function(BurpGlobals* tdgbl) case att_function_debug_info: if (tdgbl->RESTORE_format >= 10) { - get_misc_blob(tdgbl, X.RDB$DEBUG_INFO, false); + get_misc_blob(tdgbl, X.RDB$DEBUG_INFO, true); X.RDB$DEBUG_INFO.NULL = FALSE; } else @@ -5133,7 +5136,8 @@ bool get_function(BurpGlobals* tdgbl) } else { - STORE (REQUEST_HANDLE tdgbl->handles_get_function_req_handle1) + STORE (TRANSACTION_HANDLE local_trans + REQUEST_HANDLE tdgbl->handles_get_function_req_handle1) X IN RDB$FUNCTIONS X.RDB$SYSTEM_FLAG = 0; X.RDB$SYSTEM_FLAG.NULL = FALSE; @@ -5279,6 +5283,8 @@ void get_function_arg(BurpGlobals* tdgbl, bool skip_arguments) att_type attribute; scan_attr_t scan_next_attr; + Firebird::ITransaction* local_trans = tdgbl->global_trans ? tdgbl->global_trans : gds_trans; + if (skip_arguments) { skip_init(&scan_next_attr); @@ -5378,7 +5384,8 @@ void get_function_arg(BurpGlobals* tdgbl, bool skip_arguments) if (tdgbl->runtimeODS >= DB_VERSION_DDL12) { // with RDB$FIELD_PRECISION - STORE (REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) + STORE (TRANSACTION_HANDLE local_trans + REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) X IN RDB$FUNCTION_ARGUMENTS X.RDB$FIELD_SUB_TYPE.NULL = TRUE; X.RDB$CHARACTER_SET_ID.NULL = TRUE; @@ -5496,7 +5503,7 @@ void get_function_arg(BurpGlobals* tdgbl, bool skip_arguments) case att_functionarg_default_value: if (tdgbl->RESTORE_format >= 10) { - get_blr_blob(tdgbl, X.RDB$DEFAULT_VALUE, false); + get_blr_blob(tdgbl, X.RDB$DEFAULT_VALUE, true); X.RDB$DEFAULT_VALUE.NULL = FALSE; } else @@ -5587,7 +5594,8 @@ void get_function_arg(BurpGlobals* tdgbl, bool skip_arguments) else if (tdgbl->runtimeODS >= DB_VERSION_DDL10) { // with RDB$FIELD_PRECISION - STORE (REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) + STORE (TRANSACTION_HANDLE local_trans + REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) X IN RDB$FUNCTION_ARGUMENTS X.RDB$FIELD_SUB_TYPE.NULL = TRUE; X.RDB$CHARACTER_SET_ID.NULL = TRUE; @@ -5700,7 +5708,8 @@ void get_function_arg(BurpGlobals* tdgbl, bool skip_arguments) else { // without RDB$FIELD_PRECISION - STORE (REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) + STORE (TRANSACTION_HANDLE local_trans + REQUEST_HANDLE tdgbl->handles_get_function_arg_req_handle1) X IN RDB$FUNCTION_ARGUMENTS X.RDB$FIELD_SUB_TYPE.NULL = TRUE; X.RDB$CHARACTER_SET_ID.NULL = TRUE; From f516072ac1f557f245e5c4bbb3851399056d7f02 Mon Sep 17 00:00:00 2001 From: Adriano dos Santos Fernandes Date: Sun, 26 Jan 2020 12:25:12 -0300 Subject: [PATCH 38/39] Register dependencies only when "csb->csb_g_flags & csb_get_dependencies". --- src/dsql/ExprNodes.cpp | 13 ++++++++----- src/dsql/StmtNodes.cpp | 23 +++++++++++++++-------- src/jrd/par.cpp | 25 +++++++++++++++++-------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index d645e92d94..decd7fc757 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -3314,7 +3314,7 @@ DmlNode* CastNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb if (itemInfo.isSpecial()) node->itemInfo = FB_NEW_POOL(*tdbb->getDefaultPool()) ItemInfo(*tdbb->getDefaultPool(), itemInfo); - if (itemInfo.explicitCollation) + if ((csb->csb_g_flags & csb_get_dependencies) && itemInfo.explicitCollation) { CompilerScratch::Dependency dependency(obj_collation); dependency.number = INTL_TEXT_TYPE(node->castDesc); @@ -4805,10 +4805,13 @@ DmlNode* DefaultNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb->csb_blr_reader.getMetaName(relationName); csb->csb_blr_reader.getMetaName(fieldName); - CompilerScratch::Dependency dependency(obj_relation); - dependency.relation = MET_lookup_relation(tdbb, relationName); - dependency.subName = FB_NEW_POOL(pool) MetaName(fieldName); - csb->csb_dependencies.push(dependency); + if (csb->csb_g_flags & csb_get_dependencies) + { + CompilerScratch::Dependency dependency(obj_relation); + dependency.relation = MET_lookup_relation(tdbb, relationName); + dependency.subName = FB_NEW_POOL(pool) MetaName(fieldName); + csb->csb_dependencies.push(dependency); + } jrd_fld* fld = NULL; diff --git a/src/dsql/StmtNodes.cpp b/src/dsql/StmtNodes.cpp index 2e9d79e026..d9c8a98763 100644 --- a/src/dsql/StmtNodes.cpp +++ b/src/dsql/StmtNodes.cpp @@ -2174,7 +2174,7 @@ DmlNode* DeclareVariableNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerS csb->csb_map_item_info.put(Item(Item::TYPE_VARIABLE, node->varId), itemInfo); } - if (itemInfo.explicitCollation) + if ((csb->csb_g_flags & csb_get_dependencies) && itemInfo.explicitCollation) { CompilerScratch::Dependency dependency(obj_collation); dependency.number = INTL_TEXT_TYPE(node->varDesc); @@ -2715,9 +2715,13 @@ DmlNode* ErrorHandlerNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScra if (!MET_load_exception(tdbb, item)) PAR_error(csb, Arg::Gds(isc_xcpnotdef) << item.name); - CompilerScratch::Dependency dependency(obj_exception); - dependency.number = item.code; - csb->csb_dependencies.push(dependency); + if (csb->csb_g_flags & csb_get_dependencies) + { + CompilerScratch::Dependency dependency(obj_exception); + dependency.number = item.code; + csb->csb_dependencies.push(dependency); + } + break; } @@ -2886,7 +2890,7 @@ DmlNode* ExecProcedureNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr PAR_procedure_parms(tdbb, csb, procedure, node->outputMessage.getAddress(), node->outputSources.getAddress(), node->outputTargets.getAddress(), false); - if (!procedure->isSubRoutine()) + if ((csb->csb_g_flags & csb_get_dependencies) && !procedure->isSubRoutine()) { CompilerScratch::Dependency dependency(obj_procedure); dependency.procedure = procedure; @@ -4500,9 +4504,12 @@ DmlNode* ExceptionNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch if (!MET_load_exception(tdbb, *item)) PAR_error(csb, Arg::Gds(isc_xcpnotdef) << item->name); - CompilerScratch::Dependency dependency(obj_exception); - dependency.number = item->code; - csb->csb_dependencies.push(dependency); + if (csb->csb_g_flags & csb_get_dependencies) + { + CompilerScratch::Dependency dependency(obj_exception); + dependency.number = item->code; + csb->csb_dependencies.push(dependency); + } } break; diff --git a/src/jrd/par.cpp b/src/jrd/par.cpp index a0eabbe1bf..951cdeec40 100644 --- a/src/jrd/par.cpp +++ b/src/jrd/par.cpp @@ -506,9 +506,12 @@ USHORT PAR_desc(thread_db* tdbb, CompilerScratch* csb, dsc* desc, ItemInfo* item } } - CompilerScratch::Dependency dependency(obj_field); - dependency.name = name; - csb->csb_dependencies.push(dependency); + if (csb->csb_g_flags & csb_get_dependencies) + { + CompilerScratch::Dependency dependency(obj_field); + dependency.name = name; + csb->csb_dependencies.push(dependency); + } break; } @@ -568,10 +571,13 @@ USHORT PAR_desc(thread_db* tdbb, CompilerScratch* csb, dsc* desc, ItemInfo* item } } - CompilerScratch::Dependency dependency(obj_relation); - dependency.relation = MET_lookup_relation(tdbb, *relationName); - dependency.subName = fieldName; - csb->csb_dependencies.push(dependency); + if (csb->csb_g_flags & csb_get_dependencies) + { + CompilerScratch::Dependency dependency(obj_relation); + dependency.relation = MET_lookup_relation(tdbb, *relationName); + dependency.subName = fieldName; + csb->csb_dependencies.push(dependency); + } break; } @@ -582,7 +588,7 @@ USHORT PAR_desc(thread_db* tdbb, CompilerScratch* csb, dsc* desc, ItemInfo* item break; } - if (desc->getTextType() != CS_NONE) + if ((csb->csb_g_flags & csb_get_dependencies) && desc->getTextType() != CS_NONE) { CompilerScratch::Dependency dependency(obj_collation); dependency.number = INTL_TEXT_TYPE(*desc); @@ -896,6 +902,9 @@ void PAR_dependency(thread_db* tdbb, CompilerScratch* csb, StreamType stream, SS **************************************/ SET_TDBB(tdbb); + if (!(csb->csb_g_flags & csb_get_dependencies)) + return; + CompilerScratch::Dependency dependency(0); if (csb->csb_rpt[stream].csb_relation) From b5c9f2e13274cc02a8d699000b5a518daf2a6a96 Mon Sep 17 00:00:00 2001 From: firebirds <> Date: Mon, 27 Jan 2020 00:04:36 +0000 Subject: [PATCH 39/39] increment build number --- src/jrd/build_no.h | 12 ++++++------ src/misc/writeBuildNum.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jrd/build_no.h b/src/jrd/build_no.h index 314846e07e..46d566cf15 100644 --- a/src/jrd/build_no.h +++ b/src/jrd/build_no.h @@ -3,16 +3,16 @@ *** DO NOT EDIT *** TO CHANGE ANY INFORMATION IN HERE PLEASE EDIT src/misc/writeBuildNum.sh - FORMAL BUILD NUMBER:1741 + FORMAL BUILD NUMBER:1743 */ -#define PRODUCT_VER_STRING "4.0.0.1741" -#define FILE_VER_STRING "WI-T4.0.0.1741" -#define LICENSE_VER_STRING "WI-T4.0.0.1741" -#define FILE_VER_NUMBER 4, 0, 0, 1741 +#define PRODUCT_VER_STRING "4.0.0.1743" +#define FILE_VER_STRING "WI-T4.0.0.1743" +#define LICENSE_VER_STRING "WI-T4.0.0.1743" +#define FILE_VER_NUMBER 4, 0, 0, 1743 #define FB_MAJOR_VER "4" #define FB_MINOR_VER "0" #define FB_REV_NO "0" -#define FB_BUILD_NO "1741" +#define FB_BUILD_NO "1743" #define FB_BUILD_TYPE "T" #define FB_BUILD_SUFFIX "Firebird 4.0 Beta 1" diff --git a/src/misc/writeBuildNum.sh b/src/misc/writeBuildNum.sh index e5bbbefbd5..53739c0de7 100755 --- a/src/misc/writeBuildNum.sh +++ b/src/misc/writeBuildNum.sh @@ -9,7 +9,7 @@ BuildType=T MajorVer=4 MinorVer=0 RevNo=0 -BuildNum=1741 +BuildNum=1743 NowAt=`pwd` cd `dirname $0`