desktop/win32/source/loader.cxx |    8 +-
 include/rtl/bootstrap.h         |   14 ++--
 sal/rtl/bootstrap.cxx           |  127 +++++++++++++++++++++++++++-------------
 3 files changed, 99 insertions(+), 50 deletions(-)

New commits:
commit 50b14f26de63d22b9ad05ca51d9edc53e024e75e
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Tue Jan 16 14:55:03 2024 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Wed Jan 17 11:03:10 2024 +0100

    Search for load-time variables in fundamental.override.ini
    
    ...instead of arbitrarily cramming them into bootstrap.ini.  (And don't 
force
    those ini-files to have an additional [Win32] section, when
    include/rtl/bootstrap.h demands that "An ini-file is only allowed to have 
one
    section, which must be named `[Bootstrap]` with the square brackets.")
    
    Change-Id: I732bf9d771ea309eccd35b6db0f565a0c56a3c3e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162188
    Tested-by: Stephan Bergmann <[email protected]>
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/desktop/win32/source/loader.cxx b/desktop/win32/source/loader.cxx
index 40cef9e3fd4f..98efde9ec823 100644
--- a/desktop/win32/source/loader.cxx
+++ b/desktop/win32/source/loader.cxx
@@ -164,11 +164,11 @@ int officeloader_impl(bool bAllowConsole)
     }
     std::vector<std::wstring> aEscapedArgs;
 
-    // read limit values from bootstrap.ini
+    // read limit values from fundamental.override.ini
     unsigned int nMaxMemoryInMB = 0;
     bool bExcludeChildProcesses = true;
 
-    const WCHAR* szIniFile = L"\bootstrap.ini";
+    const WCHAR* szIniFile = L"\fundamental.override.ini";
     const size_t nDirLen = wcslen(szIniDirectory);
     if (wcslen(szIniFile) + nDirLen < MAX_PATH)
     {
@@ -181,8 +181,8 @@ int officeloader_impl(bool bAllowConsole)
             boost::property_tree::ptree pt;
             std::ifstream aFile(szBootstrapIni);
             boost::property_tree::ini_parser::read_ini(aFile, pt);
-            nMaxMemoryInMB = pt.get("Win32.LimitMaximumMemoryInMB", 
nMaxMemoryInMB);
-            bExcludeChildProcesses = 
pt.get("Win32.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
+            nMaxMemoryInMB = pt.get("Bootstrap.LimitMaximumMemoryInMB", 
nMaxMemoryInMB);
+            bExcludeChildProcesses = 
pt.get("Bootstrap.ExcludeChildProcessesFromLimit", bExcludeChildProcesses);
         }
         catch (...)
         {
commit f4d376e9a10a8c66f7f6ecfe6a1f4763c1927b52
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Tue Jan 16 14:41:21 2024 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Wed Jan 17 11:02:58 2024 +0100

    Introduce a fundamental.override.ini for bootstrap variables
    
    ...that is looked for next to the application and, when present, overrides 
all
    the other ways of setting bootstrap variables.  LibreOffice itself does not
    bring along such a fundamental.override.ini, but it can be convenient for an
    administrator to place one in the installation (which can then not be 
modified
    or overridden by end users).
    
    (For convenience, the naming of this ini-file starts to deviate from the 
old and
    rather pointless tradition of naming our ini-files *rc vs. *.ini on 
different
    platforms.)
    
    Change-Id: I057cc67b1af1d806587c3a4dc0bc31c28e79d22b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162187
    Tested-by: Stephan Bergmann <[email protected]>
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/include/rtl/bootstrap.h b/include/rtl/bootstrap.h
index 620a3a577944..93ece37ba95c 100644
--- a/include/rtl/bootstrap.h
+++ b/include/rtl/bootstrap.h
@@ -41,27 +41,29 @@ extern "C" {
    the next level is tried. Every query starts at the first level again, so
    that one setting may be taken from the 3rd and one from the 1st level.
 
-   1st level: explicitly set variables via rtl_bootstrap_set()
+   1st level: a fundamental.override.ini next to the application
 
-   2nd level: command line arguments. A `-env:SETTINGNAME=value` is given on
+   2nd level: explicitly set variables via rtl_bootstrap_set()
+
+   3rd level: command line arguments. A `-env:SETTINGNAME=value` is given on
    command line. This allows giving an application a certain setting, even
    if an ini-file exists (especially useful for e.g. daemons that want to
    start an executable with dynamical changing settings).
 
-   3rd level: environment variables. The application tries to get the
+   4th level: environment variables. The application tries to get the
    setting from the environment.
 
-   4th level: executable ini-file. Every application looks for an ini-file.
+   5th level: executable ini-file. Every application looks for an ini-file.
    The filename defaults to `/absolute/path/to/executable[rc|.ini]`
    without .bin or .exe suffix. The ini-filename can be
    set by the special command line parameter
    `-env:INIFILENAME=/absolute/path/to/inifile` at runtime or it may
    be set at compile time by an API-call.
 
-   5th level: URE_BOOTSTRAP ini-file. If the bootstrap variable URE_BOOTSTRAP
+   6th level: URE_BOOTSTRAP ini-file. If the bootstrap variable URE_BOOTSTRAP
    expands to the URL of an ini-file, that ini-file is searched.
 
-   6th level: default. An application can have some default settings decided
+   7th level: default. An application can have some default settings decided
    at compile time, which allow the application to run even with no
    deployment settings.
 
diff --git a/sal/rtl/bootstrap.cxx b/sal/rtl/bootstrap.cxx
index 7f5d4317636a..3ac3e4137d26 100644
--- a/sal/rtl/bootstrap.cxx
+++ b/sal/rtl/bootstrap.cxx
@@ -209,34 +209,38 @@ static void getExecutableDirectory_Impl(rtl_uString ** 
ppDirURL)
     rtl_uString_newFromStr_WithLength(ppDirURL,fileName.getStr(),nDirEnd);
 }
 
-static OUString & getIniFileName_Impl()
-{
-    static OUString aStaticName = []() {
-        OUString fileName;
+static OUString getIniFileName(bool overriding) {
+    OUString fileName;
 
 #if defined IOS
-        // On iOS hardcode the inifile as "rc" in the .app
-        // directory. Apps are self-contained anyway, there is no
-        // possibility to have several "applications" in the same
-        // installation location with different inifiles.
-        const char *inifile = [[@"vnd.sun.star.pathname:" 
stringByAppendingString: [[[NSBundle mainBundle] bundlePath] 
stringByAppendingPathComponent: @"rc"]] UTF8String];
-        fileName = OUString(inifile, strlen(inifile), RTL_TEXTENCODING_UTF8);
-        resolvePathnameUrl(&fileName);
+    // On iOS hardcode the inifile as "rc" in the .app
+    // directory. Apps are self-contained anyway, there is no
+    // possibility to have several "applications" in the same
+    // installation location with different inifiles.
+    const char *inifile = [[@"vnd.sun.star.pathname:" stringByAppendingString: 
[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: (overriding 
? @"fundamental.override.ini" : @"rc")]] UTF8String];
+    fileName = OUString(inifile, strlen(inifile), RTL_TEXTENCODING_UTF8);
+    resolvePathnameUrl(&fileName);
 #elif defined ANDROID
-        // Apps are self-contained on Android, too, can as well hardcode
-        // it as "rc" in the "/assets" directory, i.e.  inside the app's
-        // .apk (zip) archive as the /assets/rc file.
-        fileName = OUString("vnd.sun.star.pathname:/assets/rc");
-        resolvePathnameUrl(&fileName);
+    // Apps are self-contained on Android, too, can as well hardcode
+    // it as "rc" in the "/assets" directory, i.e.  inside the app's
+    // .apk (zip) archive as the /assets/rc file.
+    fileName = overriding
+        ? OUString("vnd.sun.star.pathname:/assets/fundamental.override.ini")
+        : OUString("vnd.sun.star.pathname:/assets/rc");
+    resolvePathnameUrl(&fileName);
 #else
-        if (getFromCommandLineArgs("INIFILENAME", &fileName))
-        {
-            resolvePathnameUrl(&fileName);
-        }
-        else
-        {
-            osl_getExecutableFile(&(fileName.pData));
+    if (!overriding && getFromCommandLineArgs("INIFILENAME", &fileName))
+    {
+        resolvePathnameUrl(&fileName);
+    }
+    else
+    {
+        osl_getExecutableFile(&(fileName.pData));
 
+        if (overriding) {
+            auto const i = fileName.lastIndexOf('/') + 1;
+            fileName = fileName.replaceAt(i, fileName.getLength() - i, 
u"fundamental.override.ini");
+        } else {
             // get rid of a potential executable extension
             OUString progExt = ".bin";
             if (fileName.getLength() > progExt.getLength()
@@ -254,19 +258,31 @@ static OUString & getIniFileName_Impl()
 
             // append config file suffix
             fileName += SAL_CONFIGFILE("");
+        }
 
 #ifdef MACOSX
-            // We keep only executables in the MacOS folder, and all
-            // rc files in LIBO_ETC_FOLDER (typically "Resources").
-            sal_Int32 off = fileName.lastIndexOf( "/MacOS/" );
-            if (off != -1)
-                fileName = fileName.replaceAt(off + 1, strlen("MacOS"), 
LIBO_ETC_FOLDER);
+        // We keep only executables in the MacOS folder, and all
+        // rc files in LIBO_ETC_FOLDER (typically "Resources").
+        sal_Int32 off = fileName.lastIndexOf( "/MacOS/" );
+        if (off != -1)
+            fileName = fileName.replaceAt(off + 1, strlen("MacOS"), 
LIBO_ETC_FOLDER);
 #endif
-        }
+    }
 #endif
 
-        return fileName;
-    }();
+    return fileName;
+}
+
+static OUString const & getOverrideIniFileName_Impl()
+{
+    static OUString aStaticName = getIniFileName(true);
+
+    return aStaticName;
+}
+
+static OUString & getIniFileName_Impl()
+{
+    static OUString aStaticName = getIniFileName(false);
 
     return aStaticName;
 }
@@ -284,6 +300,7 @@ static void EnsureNoFinalSlash (OUString & url)
 struct Bootstrap_Impl
 {
     sal_Int32 _nRefCount;
+    Bootstrap_Impl * _override_base_ini;
     Bootstrap_Impl * _base_ini;
 
     NameValueVector _nameValueVector;
@@ -315,23 +332,47 @@ struct Bootstrap_Impl
 
 Bootstrap_Impl::Bootstrap_Impl( OUString const & rIniName )
     : _nRefCount( 0 ),
+      _override_base_ini( nullptr ),
       _base_ini( nullptr ),
       _iniName (rIniName)
 {
-    OUString base_ini(getIniFileName_Impl());
+    OUString override_base_ini(getOverrideIniFileName_Impl());
     // normalize path
-    FileStatus status( osl_FileStatus_Mask_FileURL );
-    DirectoryItem dirItem;
-    if (DirectoryItem::get(base_ini, dirItem) == DirectoryItem::E_None &&
-        dirItem.getFileStatus(status) == DirectoryItem::E_None)
+    FileStatus override_status( osl_FileStatus_Mask_FileURL );
+    DirectoryItem override_dirItem;
+    bool skip_base_ini = false;
+    if (DirectoryItem::get(override_base_ini, override_dirItem) == 
DirectoryItem::E_None &&
+        override_dirItem.getFileStatus(override_status) == 
DirectoryItem::E_None)
     {
-        base_ini = status.getFileURL();
-        if (rIniName != base_ini)
+        override_base_ini = override_status.getFileURL();
+        if (rIniName != override_base_ini)
+        {
+            _override_base_ini = static_cast< Bootstrap_Impl * >(
+                rtl_bootstrap_args_open(override_base_ini.pData));
+        }
+        else
+        {
+            skip_base_ini = true;
+        }
+    }
+
+    if (!skip_base_ini) {
+        OUString base_ini(getIniFileName_Impl());
+        // normalize path
+        FileStatus status( osl_FileStatus_Mask_FileURL );
+        DirectoryItem dirItem;
+        if (DirectoryItem::get(base_ini, dirItem) == DirectoryItem::E_None &&
+            dirItem.getFileStatus(status) == DirectoryItem::E_None)
         {
-            _base_ini = static_cast< Bootstrap_Impl * >(
-                rtl_bootstrap_args_open(base_ini.pData));
+            base_ini = status.getFileURL();
+            if (rIniName != base_ini)
+            {
+                _base_ini = static_cast< Bootstrap_Impl * >(
+                    rtl_bootstrap_args_open(base_ini.pData));
+            }
         }
     }
+
     SAL_INFO("sal.bootstrap", "Bootstrap_Impl(): sFile=" << _iniName);
     oslFileHandle handle;
     if (!_iniName.isEmpty() &&
@@ -366,6 +407,8 @@ Bootstrap_Impl::~Bootstrap_Impl()
 {
     if (_base_ini)
         rtl_bootstrap_args_close( _base_ini );
+    if (_override_base_ini)
+        rtl_bootstrap_args_close( _override_base_ini );
 }
 
 namespace {
@@ -423,6 +466,10 @@ bool Bootstrap_Impl::getValue(
     if (override && getDirectValue(key, value, mode, requestStack))
         return true;
 
+    if (_override_base_ini != nullptr
+        && _override_base_ini->getDirectValue(key, value, mode, requestStack))
+        return true;
+
     if (key == "_OS")
     {
         rtl_uString_assign(

Reply via email to