LCOV - code coverage report
Current view: top level - unotools/source/config - bootstrap.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 87 271 32.1 %
Date: 2014-04-14 Functions: 18 39 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_folders.h>
      21             : 
      22             : #include <stdio.h>
      23             : 
      24             : #include "unotools/bootstrap.hxx"
      25             : 
      26             : #include <rtl/ustring.hxx>
      27             : #include <rtl/ustrbuf.hxx>
      28             : #include <osl/file.hxx>
      29             : #include <osl/mutex.hxx>
      30             : #include <osl/diagnose.h>
      31             : 
      32             : #include <rtl/bootstrap.hxx>
      33             : #include <rtl/instance.hxx>
      34             : #include <osl/process.h>
      35             : #include "tools/getprocessworkingdir.hxx"
      36             : 
      37             : // #define this to true, if remembering defaults is not supported properly
      38             : #define RTL_BOOTSTRAP_DEFAULTS_BROKEN true
      39             : 
      40             : #define BOOTSTRAP_ITEM_PRODUCT_KEY          "ProductKey"
      41             : #define BOOTSTRAP_ITEM_VERSIONFILE          "Location"
      42             : #define BOOTSTRAP_ITEM_BUILDID              "buildid"
      43             : #define BOOTSTRAP_ITEM_BUILDVERSION         "BuildVersion"
      44             : 
      45             : #define BOOTSTRAP_ITEM_BASEINSTALLATION     "BRAND_BASE_DIR"
      46             : #define BOOTSTRAP_ITEM_USERINSTALLATION     "UserInstallation"
      47             : 
      48             : #define BOOTSTRAP_ITEM_USERDIR              "UserDataDir"
      49             : 
      50             : #define BOOTSTRAP_DEFAULT_BASEINSTALL       "$SYSBINDIR/.."
      51             : 
      52             : #define BOOTSTRAP_DIRNAME_USERDIR           "user"
      53             : 
      54             : typedef char const * AsciiString;
      55             : 
      56             : namespace utl
      57             : {
      58             : 
      59             : // Implementation class: Bootstrap::Impl
      60             : 
      61             :     namespace
      62             :     {
      63           1 :         OUString makeImplName()
      64             :         {
      65           1 :             OUString uri;
      66           1 :             rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri);
      67           1 :             return uri + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap");
      68             :         }
      69             :     }
      70             : 
      71           1 :     class Bootstrap::Impl
      72             :     {
      73             :         const OUString m_aImplName;
      74             :     public: // struct to cache the result of a path lookup
      75           4 :         struct PathData
      76             :         {
      77             :             OUString     path;
      78             :             PathStatus   status;
      79             : 
      80           4 :             PathData()
      81             :             : path()
      82           4 :             , status(DATA_UNKNOWN)
      83           4 :             {}
      84             :         };
      85             :     public: // data members
      86             :         // base install data
      87             :         PathData aBaseInstall_;
      88             : 
      89             :         // user install data
      90             :         PathData aUserInstall_;
      91             : 
      92             :         // INI files
      93             :         PathData aBootstrapINI_;
      94             :         PathData aVersionINI_;
      95             : 
      96             :         // overall status
      97             :         Status status_;
      98             : 
      99             :     public: // construction and initialization
     100           1 :         Impl() : m_aImplName(makeImplName())
     101             :         {
     102           1 :             initialize();
     103           1 :         }
     104             : 
     105             :         void initialize();
     106             : 
     107             :         // access helper
     108             :         OUString getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const;
     109             :         bool getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const;
     110             : 
     111           0 :         OUString getImplName() const { return m_aImplName; }
     112             : 
     113             :     private: // implementation
     114             :         bool initBaseInstallationData(rtl::Bootstrap& _rData);
     115             :         bool initUserInstallationData(rtl::Bootstrap& _rData);
     116             :     };
     117             : 
     118             :     namespace
     119             :     {
     120             :         class theImpl : public rtl::Static<Bootstrap::Impl, theImpl> {};
     121             :     }
     122             : 
     123           1 :     const Bootstrap::Impl& Bootstrap::data()
     124             :     {
     125           1 :         return theImpl::get();
     126             :     }
     127             : 
     128           0 :     void Bootstrap::reloadData()
     129             :     {
     130           0 :         theImpl::get().initialize();
     131           0 :     }
     132             : 
     133             : // helper
     134             : 
     135             : typedef Bootstrap::PathStatus PathStatus;
     136             : 
     137             : sal_Unicode const cURLSeparator = '/';
     138             : 
     139             : // path status utility function
     140             : static
     141           3 : PathStatus implCheckStatusOfURL(OUString const& _sURL, osl::DirectoryItem& aDirItem)
     142             : {
     143             :     using namespace osl;
     144             : 
     145           3 :     PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
     146             : 
     147           3 :     if (!_sURL.isEmpty())
     148             :     {
     149           3 :         switch( DirectoryItem::get(_sURL, aDirItem) )
     150             :         {
     151             :         case DirectoryItem::E_None:         // Success
     152           3 :             eStatus = Bootstrap::PATH_EXISTS;
     153           3 :             break;
     154             : 
     155             :         case DirectoryItem::E_NOENT:        // No such file or directory<br>
     156           0 :             eStatus = Bootstrap::PATH_VALID;
     157           0 :             break;
     158             : 
     159             :         case DirectoryItem::E_INVAL:        // the format of the parameters was not valid<br>
     160             :         case DirectoryItem::E_NAMETOOLONG:  // File name too long<br>
     161             :         case DirectoryItem::E_NOTDIR:       // A component of the path prefix of path is not a directory<p>
     162           0 :             eStatus = Bootstrap::DATA_INVALID;
     163           0 :             break;
     164             : 
     165             :         // how to handle these ?
     166             :         case DirectoryItem::E_LOOP:         // Too many symbolic links encountered<br>
     167             :         case DirectoryItem::E_ACCES:        // permission denied<br>
     168             :         // any other error - what to do ?
     169             :         default:
     170           0 :             eStatus = Bootstrap::DATA_UNKNOWN;
     171           0 :             break;
     172             :         }
     173             :     }
     174             :     else
     175           0 :         eStatus = Bootstrap::DATA_MISSING;
     176             : 
     177           3 :     return eStatus;
     178             : }
     179             : 
     180             : static
     181           3 : bool implNormalizeURL(OUString & _sURL, osl::DirectoryItem& aDirItem)
     182             : {
     183             :     using namespace osl;
     184             : 
     185             :     OSL_PRECOND(aDirItem.is(), "Opened DirItem required");
     186             : 
     187             :     static const sal_uInt32 cosl_FileStatus_Mask = osl_FileStatus_Mask_FileURL;
     188             : 
     189           3 :     FileStatus aFileStatus(cosl_FileStatus_Mask);
     190             : 
     191           3 :     if (aDirItem.getFileStatus(aFileStatus) != DirectoryItem::E_None)
     192           0 :         return false;
     193             : 
     194           6 :     OUString aNormalizedURL = aFileStatus.getFileURL();
     195             : 
     196           3 :     if (aNormalizedURL.isEmpty())
     197           0 :         return false;
     198             : 
     199             :     // #109863# sal/osl returns final slash for file URLs contradicting
     200             :     // the URL/URI RFCs.
     201           3 :     if ( !aNormalizedURL.endsWith(OUString(cURLSeparator)) )
     202           3 :         _sURL = aNormalizedURL;
     203             :     else
     204           0 :         _sURL = aNormalizedURL.copy( 0, aNormalizedURL.getLength()-1 );
     205             : 
     206           6 :     return true;
     207             : }
     208             : 
     209             : static
     210           3 : bool implEnsureAbsolute(OUString & _rsURL) // also strips embedded dots !!
     211             : {
     212             :     using osl::File;
     213             : 
     214           3 :     OUString sBasePath;
     215           3 :     OSL_VERIFY(tools::getProcessWorkingDir(sBasePath));
     216             : 
     217           6 :     OUString sAbsolute;
     218           3 :     if ( File::E_None == File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute))
     219             :     {
     220           3 :         _rsURL = sAbsolute;
     221           3 :         return true;
     222             :     }
     223             :     else
     224             :     {
     225             :         OSL_FAIL("Could not get absolute file URL for URL");
     226           0 :         return false;
     227           3 :     }
     228             : }
     229             : 
     230             : static
     231           3 : bool implMakeAbsoluteURL(OUString & _rsPathOrURL)
     232             : {
     233             :     using namespace osl;
     234             : 
     235             :     bool bURL;
     236             : 
     237           3 :     OUString sOther;
     238             :     // check if it already was normalized
     239           3 :     if ( File::E_None == File::getSystemPathFromFileURL(_rsPathOrURL, sOther) )
     240             :     {
     241           3 :         bURL = true;
     242             :     }
     243             : 
     244           0 :     else if ( File::E_None == File::getFileURLFromSystemPath(_rsPathOrURL, sOther) )
     245             :     {
     246           0 :         _rsPathOrURL = sOther;
     247           0 :         bURL = true;
     248             :     }
     249             :     else
     250           0 :         bURL = false;
     251             : 
     252           3 :     return bURL && implEnsureAbsolute(_rsPathOrURL);
     253             : }
     254             : 
     255             : #if OSL_DEBUG_LEVEL > 0
     256             : static
     257             : PathStatus dbgCheckStatusOfURL(OUString const& _sURL)
     258             : {
     259             :     using namespace osl;
     260             : 
     261             :     DirectoryItem aDirItem;
     262             : 
     263             :     return implCheckStatusOfURL(_sURL,aDirItem);
     264             : }
     265             : 
     266             : #endif
     267             : 
     268             : static
     269           4 : PathStatus checkStatusAndNormalizeURL(OUString & _sURL)
     270             : {
     271             :     using namespace osl;
     272             : 
     273           4 :     PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
     274             : 
     275           4 :     if (_sURL.isEmpty())
     276           1 :         eStatus = Bootstrap::DATA_MISSING;
     277             : 
     278           3 :     else if ( !implMakeAbsoluteURL(_sURL) )
     279           0 :         eStatus = Bootstrap::DATA_INVALID;
     280             : 
     281             :     else
     282             :     {
     283           3 :         DirectoryItem aDirItem;
     284             : 
     285           3 :         eStatus = implCheckStatusOfURL(_sURL,aDirItem);
     286             : 
     287           3 :         if (eStatus == Bootstrap::PATH_EXISTS)
     288             :         {
     289           3 :             if (!implNormalizeURL(_sURL,aDirItem))
     290             :                 OSL_FAIL("Unexpected failure getting actual URL for existing object");
     291           3 :         }
     292             :     }
     293           4 :     return eStatus;
     294             : }
     295             : 
     296             : // helpers to build and check a nested URL
     297             : static
     298           0 : PathStatus getDerivedPath(
     299             :               OUString& _rURL,
     300             :               OUString const& _aBaseURL, PathStatus _aBaseStatus,
     301             :               OUString const& _sRelativeURL,
     302             :               rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
     303             :           )
     304             : {
     305           0 :     OUString sDerivedURL;
     306             :     OSL_PRECOND(!_rData.getFrom(_sBootstrapParameter,sDerivedURL),"Setting for derived path is already defined");
     307             :     OSL_PRECOND(!_sRelativeURL.isEmpty() && _sRelativeURL[0] != cURLSeparator,"Invalid Relative URL");
     308             : 
     309           0 :     PathStatus aStatus = _aBaseStatus;
     310             : 
     311             :     // do we have a base path ?
     312           0 :     if (!_aBaseURL.isEmpty())
     313             :     {
     314             :         OSL_PRECOND(!_aBaseURL.endsWith(OUString(cURLSeparator)), "Unexpected: base URL ends in slash");
     315             : 
     316           0 :         sDerivedURL = OUStringBuffer(_aBaseURL).append(cURLSeparator).append(_sRelativeURL).makeStringAndClear();
     317             : 
     318             :         // a derived (nested) URL can only exist or have a lesser status, if the parent exists
     319           0 :         if (aStatus == Bootstrap::PATH_EXISTS)
     320           0 :             aStatus = checkStatusAndNormalizeURL(sDerivedURL);
     321             : 
     322             :         else // the relative appendix must be valid
     323             :             OSL_ASSERT(aStatus != Bootstrap::PATH_VALID || dbgCheckStatusOfURL(sDerivedURL) == Bootstrap::PATH_VALID);
     324             : 
     325           0 :         _rData.getFrom(_sBootstrapParameter, _rURL, sDerivedURL);
     326             : 
     327             :         OSL_ENSURE(sDerivedURL == _rURL,"Could not set derived URL via Bootstrap default parameter");
     328             :         SAL_WARN_IF( !(RTL_BOOTSTRAP_DEFAULTS_BROKEN || (_rData.getFrom(_sBootstrapParameter,sDerivedURL) && sDerivedURL==_rURL)),
     329             :             "unotools.config",
     330             :             "Use of default did not affect bootstrap value");
     331             :     }
     332             :     else
     333             :     {
     334             :         // clear the result
     335           0 :         _rURL = _aBaseURL;
     336             : 
     337             :         // if we have no data it can't be a valid path
     338             :         OSL_ASSERT( aStatus > Bootstrap::PATH_VALID );
     339             :     }
     340             : 
     341           0 :     return aStatus;
     342             : }
     343             : 
     344             : static
     345             : inline
     346           0 : PathStatus getDerivedPath(
     347             :               OUString& _rURL,
     348             :               Bootstrap::Impl::PathData const& _aBaseData,
     349             :               OUString const& _sRelativeURL,
     350             :               rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
     351             :           )
     352             : {
     353           0 :     return getDerivedPath(_rURL,_aBaseData.path,_aBaseData.status,_sRelativeURL,_rData,_sBootstrapParameter);
     354             : }
     355             : 
     356             : static
     357           0 : OUString getExecutableBaseName()
     358             : {
     359           0 :     OUString sExecutable;
     360             : 
     361           0 :     if (osl_Process_E_None == osl_getExecutableFile(&sExecutable.pData))
     362             :     {
     363             :         // split the executable name
     364           0 :         sal_Int32 nSepIndex = sExecutable.lastIndexOf(cURLSeparator);
     365             : 
     366           0 :         sExecutable = sExecutable.copy(nSepIndex + 1);
     367             : 
     368             :         // ... and get the basename (strip the extension)
     369           0 :         sal_Unicode const cExtensionSep = '.';
     370             : 
     371           0 :         sal_Int32 const nExtIndex =     sExecutable.lastIndexOf(cExtensionSep);
     372           0 :         sal_Int32 const nExtLength =    sExecutable.getLength() - nExtIndex - 1;
     373           0 :         if (0 < nExtIndex && nExtLength < 4)
     374           0 :            sExecutable  = sExecutable.copy(0,nExtIndex);
     375             :     }
     376             :     else
     377             :         OSL_TRACE("Cannot get executable name: osl_getExecutableFile failed");
     378             : 
     379           0 :     return sExecutable;
     380             : }
     381             : 
     382             : static
     383             : inline
     384           4 : Bootstrap::PathStatus updateStatus(Bootstrap::Impl::PathData & _rResult)
     385             : {
     386           4 :     return _rResult.status = checkStatusAndNormalizeURL(_rResult.path);
     387             : }
     388             : 
     389             : static
     390           1 : Bootstrap::PathStatus implGetBootstrapFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rBootstrapFile)
     391             : {
     392           1 :     _rData.getIniName(_rBootstrapFile.path);
     393             : 
     394           1 :     return updateStatus(_rBootstrapFile);
     395             : }
     396             : 
     397             : static
     398           1 : Bootstrap::PathStatus implGetVersionFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rVersionFile)
     399             : {
     400           1 :     OUString const csVersionFileItem(BOOTSTRAP_ITEM_VERSIONFILE);
     401             : 
     402           1 :     _rData.getFrom(csVersionFileItem,_rVersionFile.path);
     403             : 
     404           1 :     return updateStatus(_rVersionFile);
     405             : }
     406             : 
     407             : // Error reporting
     408             : 
     409             : static char const IS_MISSING[] = "is missing";
     410             : static char const IS_INVALID[] = "is corrupt";
     411             : static char const PERIOD[] = ". ";
     412             : 
     413           0 : static void addFileError(OUStringBuffer& _rBuf, OUString const& _aPath, AsciiString _sWhat)
     414             : {
     415           0 :     OUString sSimpleFileName = _aPath.copy(1 +_aPath.lastIndexOf(cURLSeparator));
     416             : 
     417           0 :     _rBuf.appendAscii("The configuration file");
     418           0 :     _rBuf.appendAscii(" '").append(sSimpleFileName).appendAscii("' ");
     419           0 :     _rBuf.appendAscii(_sWhat).appendAscii(PERIOD);
     420           0 : }
     421             : 
     422           0 : static void addMissingDirectoryError(OUStringBuffer& _rBuf, OUString const& _aPath)
     423             : {
     424           0 :     _rBuf.appendAscii("The configuration directory");
     425           0 :     _rBuf.appendAscii(" '").append(_aPath).appendAscii("' ");
     426           0 :     _rBuf.appendAscii(IS_MISSING).appendAscii(PERIOD);
     427           0 : }
     428             : 
     429           0 : static void addUnexpectedError(OUStringBuffer& _rBuf, AsciiString _sExtraInfo = NULL)
     430             : {
     431           0 :     if (NULL == _sExtraInfo)
     432           0 :         _sExtraInfo = "An internal failure occurred";
     433             : 
     434           0 :     _rBuf.appendAscii(_sExtraInfo).appendAscii(PERIOD);
     435           0 : }
     436             : 
     437           0 : static Bootstrap::FailureCode describeError(OUStringBuffer& _rBuf, Bootstrap::Impl const& _rData)
     438             : {
     439           0 :     Bootstrap::FailureCode eErrCode = Bootstrap::INVALID_BOOTSTRAP_DATA;
     440             : 
     441           0 :     _rBuf.appendAscii("The program cannot be started. ");
     442             : 
     443           0 :     switch (_rData.aUserInstall_.status)
     444             :     {
     445             :     case Bootstrap::PATH_EXISTS:
     446           0 :         switch (_rData.aBaseInstall_.status)
     447             :         {
     448             :         case Bootstrap::PATH_VALID:
     449           0 :             addMissingDirectoryError(_rBuf, _rData.aBaseInstall_.path);
     450           0 :             eErrCode = Bootstrap::MISSING_INSTALL_DIRECTORY;
     451           0 :             break;
     452             : 
     453             :         case Bootstrap::DATA_INVALID:
     454           0 :             addUnexpectedError(_rBuf,"The installation path is invalid");
     455           0 :             break;
     456             : 
     457             :         case Bootstrap::DATA_MISSING:
     458           0 :             addUnexpectedError(_rBuf,"The installation path is not available");
     459           0 :             break;
     460             : 
     461             :         case Bootstrap::PATH_EXISTS: // seems to be all fine (?)
     462           0 :             addUnexpectedError(_rBuf,"");
     463           0 :             break;
     464             : 
     465             :         default: OSL_ASSERT(false);
     466           0 :             addUnexpectedError(_rBuf);
     467           0 :             break;
     468             :         }
     469           0 :         break;
     470             : 
     471             :     case Bootstrap::PATH_VALID:
     472           0 :         addMissingDirectoryError(_rBuf, _rData.aUserInstall_.path);
     473           0 :         eErrCode = Bootstrap::MISSING_USER_DIRECTORY;
     474           0 :         break;
     475             : 
     476             :         // else fall through
     477             :     case Bootstrap::DATA_INVALID:
     478           0 :         if (_rData.aVersionINI_.status == Bootstrap::PATH_EXISTS)
     479             :         {
     480           0 :             addFileError(_rBuf, _rData.aVersionINI_.path, IS_INVALID);
     481           0 :             eErrCode = Bootstrap::INVALID_VERSION_FILE_ENTRY;
     482           0 :             break;
     483             :         }
     484             :         // else fall through
     485             : 
     486             :     case Bootstrap::DATA_MISSING:
     487           0 :         switch (_rData.aVersionINI_.status)
     488             :         {
     489             :         case Bootstrap::PATH_EXISTS:
     490           0 :             addFileError(_rBuf, _rData.aVersionINI_.path, "does not support the current version");
     491           0 :             eErrCode = Bootstrap::MISSING_VERSION_FILE_ENTRY;
     492           0 :             break;
     493             : 
     494             :         case Bootstrap::PATH_VALID:
     495           0 :             addFileError(_rBuf, _rData.aVersionINI_.path, IS_MISSING);
     496           0 :             eErrCode = Bootstrap::MISSING_VERSION_FILE;
     497           0 :             break;
     498             : 
     499             :         default:
     500           0 :             switch (_rData.aBootstrapINI_.status)
     501             :             {
     502             :             case Bootstrap::PATH_EXISTS:
     503           0 :                 addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_INVALID);
     504             : 
     505           0 :                 if (_rData.aVersionINI_.status == Bootstrap::DATA_MISSING)
     506           0 :                     eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY;
     507             :                 else
     508           0 :                     eErrCode = Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY;
     509           0 :                 break;
     510             : 
     511             :             case Bootstrap::DATA_INVALID: OSL_ASSERT(false);
     512             :             case Bootstrap::PATH_VALID:
     513           0 :                 addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_MISSING);
     514           0 :                 eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE;
     515           0 :                 break;
     516             : 
     517             :             default:
     518           0 :                 addUnexpectedError(_rBuf);
     519           0 :                 break;
     520             :             }
     521           0 :             break;
     522             :         }
     523           0 :         break;
     524             : 
     525             :     default: OSL_ASSERT(false);
     526           0 :         addUnexpectedError(_rBuf);
     527           0 :         break;
     528             :     }
     529             : 
     530           0 :     return eErrCode;
     531             : }
     532             : 
     533             : // class Bootstrap
     534             : 
     535           0 : OUString Bootstrap::getProductKey()
     536             : {
     537           0 :     OUString const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY);
     538             : 
     539           0 :     OUString const sDefaultProductKey = getExecutableBaseName();
     540             : 
     541           0 :     return data().getBootstrapValue( csProductKeyItem, sDefaultProductKey );
     542             : }
     543             : 
     544           0 : OUString Bootstrap::getProductKey(OUString const& _sDefault)
     545             : {
     546           0 :     OUString const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY);
     547             : 
     548           0 :     return data().getBootstrapValue( csProductKeyItem, _sDefault );
     549             : }
     550             : 
     551           0 : OUString Bootstrap::getBuildVersion(OUString const& _sDefault)
     552             : {
     553           0 :     OUString const csBuildVersionItem(BOOTSTRAP_ITEM_BUILDVERSION);
     554             : 
     555           0 :     OUString sBuildVersion;
     556             :     // read BuildVersion from version.ini (versionrc)
     557           0 :     data().getVersionValue( csBuildVersionItem, sBuildVersion, _sDefault );
     558           0 :     return sBuildVersion;
     559             : }
     560             : 
     561           0 : OUString Bootstrap::getBuildIdData(OUString const& _sDefault)
     562             : {
     563           0 :     OUString const csBuildIdItem(BOOTSTRAP_ITEM_BUILDID);
     564             : 
     565           0 :     OUString sBuildId;
     566             :     // read buildid from version.ini (versionrc), if it doesn't exist or buildid is empty
     567           0 :     if ( !data().getVersionValue( csBuildIdItem, sBuildId, _sDefault ) ||
     568           0 :          sBuildId.isEmpty() )
     569             :          // read buildid from bootstrap.ini (bootstraprc)
     570           0 :         sBuildId = data().getBootstrapValue( csBuildIdItem, _sDefault );
     571           0 :     return sBuildId;
     572             : }
     573             : 
     574           0 : Bootstrap::PathStatus Bootstrap::locateBaseInstallation(OUString& _rURL)
     575             : {
     576           0 :     Impl::PathData const& aPathData = data().aBaseInstall_;
     577             : 
     578           0 :     _rURL = aPathData.path;
     579           0 :     return aPathData.status;
     580             : }
     581             : 
     582           1 : PathStatus Bootstrap::locateUserInstallation(OUString& _rURL)
     583             : {
     584           1 :     Impl::PathData const& aPathData = data().aUserInstall_;
     585             : 
     586           1 :     _rURL = aPathData.path;
     587           1 :     return aPathData.status;
     588             : }
     589             : 
     590           0 : PathStatus Bootstrap::locateUserData(OUString& _rURL)
     591             : {
     592           0 :     OUString const csUserDirItem(BOOTSTRAP_ITEM_USERDIR);
     593             : 
     594           0 :     rtl::Bootstrap aData( data().getImplName() );
     595             : 
     596           0 :     if ( aData.getFrom(csUserDirItem, _rURL) )
     597             :     {
     598           0 :         return checkStatusAndNormalizeURL(_rURL);
     599             :     }
     600             :     else
     601             :     {
     602           0 :         OUString const csUserDir(BOOTSTRAP_DIRNAME_USERDIR);
     603           0 :         return getDerivedPath(_rURL, data().aUserInstall_ ,csUserDir, aData, csUserDirItem);
     604           0 :     }
     605             : }
     606             : 
     607           0 : PathStatus Bootstrap::locateBootstrapFile(OUString& _rURL)
     608             : {
     609           0 :     Impl::PathData const& aPathData = data().aBootstrapINI_;
     610             : 
     611           0 :     _rURL = aPathData.path;
     612           0 :     return aPathData.status;
     613             : }
     614             : 
     615           0 : PathStatus Bootstrap::locateVersionFile(OUString& _rURL)
     616             : {
     617           0 :     Impl::PathData const& aPathData = data().aVersionINI_;
     618             : 
     619           0 :     _rURL = aPathData.path;
     620           0 :     return aPathData.status;
     621             : }
     622             : 
     623           0 : Bootstrap::Status Bootstrap::checkBootstrapStatus(OUString& _rDiagnosticMessage, FailureCode& _rErrCode)
     624             : {
     625           0 :     Impl const& aData = data();
     626             : 
     627           0 :     Status result = aData.status_;
     628             : 
     629             :     // maybe do further checks here
     630             : 
     631           0 :     OUStringBuffer sErrorBuffer;
     632           0 :     if (result != DATA_OK)
     633           0 :         _rErrCode = describeError(sErrorBuffer,aData);
     634             : 
     635             :     else
     636           0 :         _rErrCode = NO_FAILURE;
     637             : 
     638           0 :     _rDiagnosticMessage = sErrorBuffer.makeStringAndClear();
     639             : 
     640           0 :     return result;
     641             : }
     642             : 
     643             : // class Bootstrap::Impl
     644             : 
     645           1 : bool Bootstrap::Impl::initBaseInstallationData(rtl::Bootstrap& _rData)
     646             : {
     647           1 :     OUString const csBaseInstallItem( BOOTSTRAP_ITEM_BASEINSTALLATION );
     648           2 :     OUString const csBaseInstallDefault( BOOTSTRAP_DEFAULT_BASEINSTALL );
     649             : 
     650           1 :     _rData.getFrom(csBaseInstallItem, aBaseInstall_.path, csBaseInstallDefault);
     651             : 
     652           1 :     bool bResult = (PATH_EXISTS == updateStatus(aBaseInstall_));
     653             : 
     654           1 :     implGetBootstrapFile(_rData, aBootstrapINI_);
     655             : 
     656           2 :     return bResult;
     657             : }
     658             : 
     659           1 : bool Bootstrap::Impl::initUserInstallationData(rtl::Bootstrap& _rData)
     660             : {
     661           1 :     OUString const csUserInstallItem( BOOTSTRAP_ITEM_USERINSTALLATION );
     662             : 
     663           1 :     if (_rData.getFrom(csUserInstallItem, aUserInstall_.path))
     664             :     {
     665           1 :         updateStatus(aUserInstall_);
     666             :     }
     667             :     else
     668             :     {
     669             :         // should we do just this
     670           0 :         aUserInstall_.status = DATA_MISSING;
     671             : 
     672             :         // .. or this - look for a single-user user directory ?
     673           0 :         OUString const csUserDirItem(BOOTSTRAP_ITEM_USERDIR);
     674           0 :         OUString sDummy;
     675             :         // look for $BASEINSTALLATION/user only if default UserDir setting is used
     676           0 :         if (! _rData.getFrom(csUserDirItem, sDummy))
     677             :         {
     678           0 :             OUString const csUserDir(BOOTSTRAP_DIRNAME_USERDIR);
     679             : 
     680           0 :             if ( PATH_EXISTS == getDerivedPath(sDummy, aBaseInstall_, csUserDir, _rData, csUserDirItem) )
     681           0 :                 aUserInstall_ = aBaseInstall_;
     682           0 :         }
     683             :     }
     684             : 
     685           1 :     bool bResult = (PATH_EXISTS == aUserInstall_.status);
     686             : 
     687           1 :     implGetVersionFile(_rData, aVersionINI_);
     688             : 
     689           1 :     return bResult;
     690             : }
     691             : 
     692           1 : void Bootstrap::Impl::initialize()
     693             : {
     694           1 :     rtl::Bootstrap aData( m_aImplName );
     695             : 
     696           1 :     if (!initBaseInstallationData(aData))
     697             :     {
     698           0 :         status_ = INVALID_BASE_INSTALL;
     699             :     }
     700           1 :     else if (!initUserInstallationData(aData))
     701             :     {
     702           0 :         status_ = INVALID_USER_INSTALL;
     703             : 
     704           0 :         if (aUserInstall_.status >= DATA_MISSING)
     705             :         {
     706           0 :             switch (aVersionINI_.status)
     707             :             {
     708             :             case PATH_EXISTS:
     709             :             case PATH_VALID:
     710           0 :                 status_ = MISSING_USER_INSTALL;
     711           0 :                 break;
     712             : 
     713             :             case DATA_INVALID:
     714             :             case DATA_MISSING:
     715           0 :                 status_ = INVALID_BASE_INSTALL;
     716           0 :                 break;
     717             :             default:
     718           0 :                 break;
     719             :             }
     720             :         }
     721             :     }
     722             :     else
     723             :     {
     724           1 :         status_ = DATA_OK;
     725           1 :     }
     726           1 : }
     727             : 
     728           0 : OUString Bootstrap::Impl::getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const
     729             : {
     730           0 :     rtl::Bootstrap aData( m_aImplName );
     731             : 
     732           0 :     OUString sResult;
     733           0 :     aData.getFrom(_sName,sResult,_sDefault);
     734           0 :     return sResult;
     735             : }
     736             : 
     737           0 : bool Bootstrap::Impl::getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const
     738             : {
     739             :     // try to open version.ini (versionrc)
     740           0 :     OUString uri;
     741           0 :     rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri);
     742           0 :     rtl::Bootstrap aData( uri + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("version") );
     743           0 :     if ( aData.getHandle() == NULL )
     744             :         // version.ini (versionrc) doesn't exist
     745           0 :         return false;
     746             : 
     747             :     // read value
     748           0 :     aData.getFrom(_sName,_rValue,_sDefault);
     749           0 :     return true;
     750             : }
     751             : 
     752             : } // namespace utl
     753             : 
     754             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10