update dev300-m58
[ooovba.git] / unotools / source / config / bootstrap.cxx
blob55dce6feabda8051fed169d528af4c6131b45e33
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bootstrap.cxx,v $
10 * $Revision: 1.28.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_unotools.hxx"
34 #include <stdio.h>
36 #include "unotools/bootstrap.hxx"
38 // ---------------------------------------------------------------------------------------
39 #include <rtl/ustring.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <osl/file.hxx>
42 #include <osl/mutex.hxx>
43 #include <osl/diagnose.h>
44 // ---------------------------------------------------------------------------------------
45 #include <rtl/bootstrap.hxx>
46 #include <osl/process.h> // for osl_getExecutableFile
47 #include "tools/getprocessworkingdir.hxx"
49 // ---------------------------------------------------------------------------------------
50 // #define this to a non-zero value, if remembering defaults is not supported properly
51 #define RTL_BOOTSTRAP_DEFAULTS_BROKEN 1
53 // ---------------------------------------------------------------------------------------
54 #define BOOTSTRAP_DATA_NAME SAL_CONFIGFILE("bootstrap")
56 #define BOOTSTRAP_ITEM_PRODUCT_KEY "ProductKey"
57 #define BOOTSTRAP_ITEM_PRODUCT_SOURCE "ProductSource"
58 #define BOOTSTRAP_ITEM_VERSIONFILE "Location"
59 #define BOOTSTRAP_ITEM_BUILDID "buildid"
61 #define BOOTSTRAP_ITEM_BASEINSTALLATION "BaseInstallation"
62 #define BOOTSTRAP_ITEM_USERINSTALLATION "UserInstallation"
64 #define BOOTSTRAP_ITEM_SHAREDIR "SharedDataDir"
65 #define BOOTSTRAP_ITEM_USERDIR "UserDataDir"
67 #define BOOTSTRAP_DEFAULT_BASEINSTALL "$SYSBINDIR/.."
69 #define BOOTSTRAP_DIRNAME_SHAREDIR "share"
70 #define BOOTSTRAP_DIRNAME_USERDIR "user"
72 #define VERSIONFILE_SECTION "Versions"
74 #define SETUP_DATA_NAME SAL_CONFIGFILE("setup")
75 #define SETUP_ITEM_ALLUSERS "ALLUSERS"
76 // ---------------------------------------------------------------------------------------
77 typedef char const * AsciiString;
78 // ---------------------------------------------------------------------------------------
80 namespace utl
82 // ---------------------------------------------------------------------------------------
83 using ::rtl::OUString;
84 using ::rtl::OUStringBuffer;
85 using ::rtl::OString;
87 // ---------------------------------------------------------------------------------------
88 // Implementation class: Bootstrap::Impl
89 // ---------------------------------------------------------------------------------------
91 class Bootstrap::Impl
93 OUString const m_aImplName;
94 public: // struct to cache the result of a path lookup
95 struct PathData
97 OUString path;
98 PathStatus status;
100 PathData()
101 : path()
102 , status(DATA_UNKNOWN)
105 public: // data members
106 // base install data
107 PathData aBaseInstall_;
109 // user install data
110 PathData aUserInstall_;
112 // INI files
113 PathData aBootstrapINI_;
114 PathData aVersionINI_;
116 // overall status
117 Status status_;
119 public: // construction and initialization
120 explicit
121 Impl(OUString const& _aImplName)
122 : m_aImplName(_aImplName)
124 status_ = initialize();
127 Status initialize();
129 // access helper
130 OUString getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const;
131 sal_Bool getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const;
133 OUString getImplName() const { return m_aImplName; }
135 private: // implementation
136 bool initBaseInstallationData(rtl::Bootstrap& _rData);
137 bool initUserInstallationData(rtl::Bootstrap& _rData);
139 // ---------------------------------------------------------------------------------------
140 static OUString getExecutableDirectory();
141 // ---------------------------------------------------------------------------------------
143 static Bootstrap::Impl* s_pData = NULL;
145 Bootstrap::Impl const& Bootstrap::data()
148 if (!s_pData)
150 using namespace osl;
151 MutexGuard aGuard( Mutex::getGlobalMutex() );
153 // static Impl s_theData(getExecutableDirectory() + OUString(RTL_CONSTASCII_USTRINGPARAM("/"BOOTSTRAP_DATA_NAME)));
154 // s_pData = &s_theData;
155 rtl::OUString uri;
156 rtl::Bootstrap::get(
157 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BRAND_BASE_DIR")), uri);
158 s_pData = new Impl(uri + OUString(RTL_CONSTASCII_USTRINGPARAM("/program/"BOOTSTRAP_DATA_NAME)));
160 return *s_pData;
163 void Bootstrap::reloadData()
165 if (s_pData != NULL) {
166 delete s_pData;
167 s_pData = NULL;
171 // ---------------------------------------------------------------------------------------
172 // helper
173 // ---------------------------------------------------------------------------------------
175 typedef Bootstrap::PathStatus PathStatus;
177 sal_Unicode const cURLSeparator = '/';
179 // ---------------------------------------------------------------------------------------
180 static
181 inline
182 OUString getURLSeparator()
184 static OUString theSep(&cURLSeparator,1);
185 return theSep;
188 // ---------------------------------------------------------------------------------------
189 // path status utility function
190 static
191 PathStatus implCheckStatusOfURL(OUString const& _sURL, osl::DirectoryItem& aDirItem)
193 using namespace osl;
195 PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
197 if (_sURL.getLength() != 0)
199 switch( DirectoryItem::get(_sURL, aDirItem) )
201 case DirectoryItem::E_None: // Success
202 eStatus = Bootstrap::PATH_EXISTS;
203 break;
205 case DirectoryItem::E_NOENT: // No such file or directory<br>
206 eStatus = Bootstrap::PATH_VALID;
207 break;
209 case DirectoryItem::E_INVAL: // the format of the parameters was not valid<br>
210 case DirectoryItem::E_NAMETOOLONG: // File name too long<br>
211 case DirectoryItem::E_NOTDIR: // A component of the path prefix of path is not a directory<p>
212 eStatus = Bootstrap::DATA_INVALID;
213 break;
215 // how to handle these ?
216 case DirectoryItem::E_LOOP: // Too many symbolic links encountered<br>
217 case DirectoryItem::E_ACCES: // permission denied<br>
218 // any other error - what to do ?
219 default:
220 eStatus = Bootstrap::DATA_UNKNOWN;
221 break;
224 else
225 eStatus = Bootstrap::DATA_MISSING;
227 return eStatus;
229 // ---------------------------------------------------------------------------------------
231 static
232 bool implNormalizeURL(OUString & _sURL, osl::DirectoryItem& aDirItem)
234 using namespace osl;
236 OSL_PRECOND(aDirItem.is(), "Opened DirItem required");
238 static const sal_uInt32 cFileStatusMask = FileStatusMask_FileURL;
240 FileStatus aFileStatus(cFileStatusMask);
242 if (aDirItem.getFileStatus(aFileStatus) != DirectoryItem::E_None)
243 return false;
245 OUString aNormalizedURL = aFileStatus.getFileURL();
247 if (aNormalizedURL.getLength() == 0)
248 return false;
250 // #109863# sal/osl returns final slash for file URLs contradicting
251 // the URL/URI RFCs.
252 if ( aNormalizedURL.getStr()[aNormalizedURL.getLength()-1] != cURLSeparator )
253 _sURL = aNormalizedURL;
254 else
255 _sURL = aNormalizedURL.copy( 0, aNormalizedURL.getLength()-1 );
257 return true;
259 // ---------------------------------------------------------------------------------------
260 static
261 bool implEnsureAbsolute(OUString & _rsURL) // also strips embedded dots !!
263 using osl::File;
265 OUString sBasePath;
266 OSL_VERIFY(tools::getProcessWorkingDir(&sBasePath));
268 OUString sAbsolute;
269 if ( File::E_None == File::getAbsoluteFileURL(sBasePath, _rsURL, sAbsolute))
271 _rsURL = sAbsolute;
272 return true;
274 else
276 OSL_ENSURE(false, "Could not get absolute file URL for URL");
277 return false;
280 /* old code to strip embedded dots
281 static OUString const sDots(RTL_CONSTASCII_USTRINGPARAM("/.."));
283 sal_Int32 nDotsIndex = _rsURL.indexOf(sDots);
284 while (nDotsIndex >= 0)
286 OSL_ASSERT(_rsURL.indexOf(sDots) == nDotsIndex);
288 sal_Int32 nStripIndex = _rsURL.lastIndexOf(cURLSeparator,nDotsIndex);
289 if (nStripIndex < 0 || nStripIndex+1 == nDotsIndex)
291 OSL_TRACE("Invalid use of dots in bootstrap URL");
292 return false;
294 _rsURL = _rsURL.copy(0,nStripIndex) + _rsURL.copy(nDotsIndex + sDots.getLength());
296 nDotsIndex = _rsURL.indexOf(sDots,nStripIndex);
298 return true;
302 // ---------------------------------------------------------------------------------------
304 static
305 bool implMakeAbsoluteURL(OUString & _rsPathOrURL)
307 using namespace osl;
309 bool bURL;
311 OUString sOther;
312 // check if it already was normalized
313 if ( File::E_None == File::getSystemPathFromFileURL(_rsPathOrURL, sOther) )
315 bURL = true;
318 else if ( File::E_None == File::getFileURLFromSystemPath(_rsPathOrURL, sOther) )
320 _rsPathOrURL = sOther;
321 bURL = true;
323 else
324 bURL = false;
326 return bURL && implEnsureAbsolute(_rsPathOrURL);
328 // ---------------------------------------------------------------------------------------
329 #if OSL_DEBUG_LEVEL > 0
330 static
331 PathStatus dbgCheckStatusOfURL(OUString const& _sURL)
333 using namespace osl;
335 DirectoryItem aDirItem;
337 return implCheckStatusOfURL(_sURL,aDirItem);
339 // ---------------------------------------------------------------------------------------
340 #endif
342 static
343 PathStatus checkStatusAndNormalizeURL(OUString & _sURL)
345 using namespace osl;
347 PathStatus eStatus = Bootstrap::DATA_UNKNOWN;
349 if (_sURL.getLength() == 0)
350 eStatus = Bootstrap::DATA_MISSING;
352 else if ( !implMakeAbsoluteURL(_sURL) )
353 eStatus = Bootstrap::DATA_INVALID;
355 else
357 DirectoryItem aDirItem;
359 eStatus = implCheckStatusOfURL(_sURL,aDirItem);
361 if (eStatus == Bootstrap::PATH_EXISTS)
363 if (!implNormalizeURL(_sURL,aDirItem))
364 OSL_ENSURE(false,"Unexpected failure getting actual URL for existing object");
367 return eStatus;
371 // ----------------------------------------------------------------------------------
372 // helpers to build and check a nested URL
373 static
374 PathStatus getDerivedPath(
375 OUString& _rURL,
376 OUString const& _aBaseURL, PathStatus _aBaseStatus,
377 OUString const& _sRelativeURL,
378 rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
381 OUString sDerivedURL;
383 OSL_PRECOND(!_rData.getFrom(_sBootstrapParameter,sDerivedURL),"Setting for derived path is already defined");
384 OSL_PRECOND(_sRelativeURL.getLength() != 0 && _sRelativeURL[0] != cURLSeparator,"Invalid Relative URL");
386 PathStatus aStatus = _aBaseStatus;
388 // do we have a base path ?
389 if (_aBaseURL.getLength())
391 OSL_PRECOND(_aBaseURL[_aBaseURL.getLength()-1] != cURLSeparator,"Unexpected: base URL ends in slash");
393 sDerivedURL = _aBaseURL + getURLSeparator() + _sRelativeURL;
395 // a derived (nested) URL can only exist or have a lesser status, if the parent exists
396 if (aStatus == Bootstrap::PATH_EXISTS)
397 aStatus = checkStatusAndNormalizeURL(sDerivedURL);
399 else // the relative appendix must be valid
400 OSL_ASSERT(aStatus != Bootstrap::PATH_VALID || dbgCheckStatusOfURL(sDerivedURL) == Bootstrap::PATH_VALID);
402 _rData.getFrom(_sBootstrapParameter, _rURL, sDerivedURL);
404 OSL_ENSURE(sDerivedURL == _rURL,"Could not set derived URL via Bootstrap default parameter");
405 OSL_POSTCOND(RTL_BOOTSTRAP_DEFAULTS_BROKEN ||
406 _rData.getFrom(_sBootstrapParameter,sDerivedURL) && sDerivedURL==_rURL,"Use of default did not affect bootstrap value");
408 else
410 // clear the result
411 _rURL = _aBaseURL;
413 // if we have no data it can't be a valid path
414 OSL_ASSERT( aStatus > Bootstrap::PATH_VALID );
418 return aStatus;
421 // ----------------------------------------------------------------------------------
422 static
423 inline
424 PathStatus getDerivedPath(
425 OUString& _rURL,
426 Bootstrap::Impl::PathData const& _aBaseData,
427 OUString const& _sRelativeURL,
428 rtl::Bootstrap& _rData, OUString const& _sBootstrapParameter
431 return getDerivedPath(_rURL,_aBaseData.path,_aBaseData.status,_sRelativeURL,_rData,_sBootstrapParameter);
434 // ---------------------------------------------------------------------------------------
436 static
437 OUString getExecutableBaseName()
439 OUString sExecutable;
441 if (osl_Process_E_None == osl_getExecutableFile(&sExecutable.pData))
443 // split the executable name
444 sal_Int32 nSepIndex = sExecutable.lastIndexOf(cURLSeparator);
446 sExecutable = sExecutable.copy(nSepIndex + 1);
448 // ... and get the basename (strip the extension)
449 sal_Unicode const cExtensionSep = '.';
451 sal_Int32 const nExtIndex = sExecutable.lastIndexOf(cExtensionSep);
452 sal_Int32 const nExtLength = sExecutable.getLength() - nExtIndex - 1;
453 if (0 < nExtIndex && nExtLength < 4)
454 sExecutable = sExecutable.copy(0,nExtIndex);
456 else
457 OSL_TRACE("Cannot get executable name: osl_getExecutableFile failed\n");
459 return sExecutable;
462 // ---------------------------------------------------------------------------------------
463 static
464 OUString getExecutableDirectory()
466 OUString sFileName;
467 OSL_VERIFY(osl_Process_E_None == osl_getExecutableFile(&sFileName.pData));
469 sal_Int32 nDirEnd = sFileName.lastIndexOf(cURLSeparator);
471 OSL_ENSURE(nDirEnd >= 0, "Cannot locate executable directory");
473 return sFileName.copy(0,nDirEnd);
476 // ----------------------------------------------------------------------------------
478 static
479 inline
480 Bootstrap::PathStatus updateStatus(Bootstrap::Impl::PathData & _rResult)
482 return _rResult.status = checkStatusAndNormalizeURL(_rResult.path);
484 // ---------------------------------------------------------------------------------------
486 static
487 Bootstrap::PathStatus implGetBootstrapFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rBootstrapFile)
489 _rData.getIniName(_rBootstrapFile.path);
491 return updateStatus(_rBootstrapFile);
493 // ---------------------------------------------------------------------------------------
495 static
496 Bootstrap::PathStatus implGetVersionFile(rtl::Bootstrap& _rData, Bootstrap::Impl::PathData & _rVersionFile)
498 OUString const csVersionFileItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_VERSIONFILE));
500 _rData.getFrom(csVersionFileItem,_rVersionFile.path);
502 return updateStatus(_rVersionFile);
504 // ---------------------------------------------------------------------------------------
505 // Error reporting
507 static char const IS_MISSING[] = "is missing";
508 static char const IS_INVALID[] = "is corrupt";
509 static char const PERIOD[] = ". ";
511 // ---------------------------------------------------------------------------------------
512 static void addFileError(OUStringBuffer& _rBuf, OUString const& _aPath, AsciiString _sWhat)
514 OUString sSimpleFileName = _aPath.copy(1 +_aPath.lastIndexOf(cURLSeparator));
516 _rBuf.appendAscii("The configuration file");
517 _rBuf.appendAscii(" '").append(sSimpleFileName).appendAscii("' ");
518 _rBuf.appendAscii(_sWhat).appendAscii(PERIOD);
520 // ---------------------------------------------------------------------------------------
522 static void addMissingDirectoryError(OUStringBuffer& _rBuf, OUString const& _aPath)
524 _rBuf.appendAscii("The configuration directory");
525 _rBuf.appendAscii(" '").append(_aPath).appendAscii("' ");
526 _rBuf.appendAscii(IS_MISSING).appendAscii(PERIOD);
528 // ---------------------------------------------------------------------------------------
530 static void addUnexpectedError(OUStringBuffer& _rBuf, AsciiString _sExtraInfo = NULL)
532 if (NULL == _sExtraInfo)
533 _sExtraInfo = "An internal failure occurred";
535 _rBuf.appendAscii(_sExtraInfo).appendAscii(PERIOD);
537 // ---------------------------------------------------------------------------------------
539 static Bootstrap::FailureCode describeError(OUStringBuffer& _rBuf, Bootstrap::Impl const& _rData)
541 Bootstrap::FailureCode eErrCode = Bootstrap::INVALID_BOOTSTRAP_DATA;
543 _rBuf.appendAscii("The program cannot be started. ");
545 switch (_rData.aUserInstall_.status)
547 case Bootstrap::PATH_EXISTS:
548 switch (_rData.aBaseInstall_.status)
550 case Bootstrap::PATH_VALID:
551 addMissingDirectoryError(_rBuf, _rData.aBaseInstall_.path);
552 eErrCode = Bootstrap::MISSING_INSTALL_DIRECTORY;
553 break;
555 case Bootstrap::DATA_INVALID:
556 addUnexpectedError(_rBuf,"The installation path is invalid");
557 break;
559 case Bootstrap::DATA_MISSING:
560 addUnexpectedError(_rBuf,"The installation path is not available");
561 break;
563 case Bootstrap::PATH_EXISTS: // seems to be all fine (?)
564 addUnexpectedError(_rBuf,"");
565 break;
567 default: OSL_ASSERT(false);
568 addUnexpectedError(_rBuf);
569 break;
571 break;
573 case Bootstrap::PATH_VALID:
574 addMissingDirectoryError(_rBuf, _rData.aUserInstall_.path);
575 eErrCode = Bootstrap::MISSING_USER_DIRECTORY;
576 break;
578 // else fall through
579 case Bootstrap::DATA_INVALID:
580 if (_rData.aVersionINI_.status == Bootstrap::PATH_EXISTS)
582 addFileError(_rBuf, _rData.aVersionINI_.path, IS_INVALID);
583 eErrCode = Bootstrap::INVALID_VERSION_FILE_ENTRY;
584 break;
586 // else fall through
588 case Bootstrap::DATA_MISSING:
589 switch (_rData.aVersionINI_.status)
591 case Bootstrap::PATH_EXISTS:
592 addFileError(_rBuf, _rData.aVersionINI_.path, "does not support the current version");
593 eErrCode = Bootstrap::MISSING_VERSION_FILE_ENTRY;
594 break;
596 case Bootstrap::PATH_VALID:
597 addFileError(_rBuf, _rData.aVersionINI_.path, IS_MISSING);
598 eErrCode = Bootstrap::MISSING_VERSION_FILE;
599 break;
601 default:
602 switch (_rData.aBootstrapINI_.status)
604 case Bootstrap::PATH_EXISTS:
605 addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_INVALID);
607 if (_rData.aVersionINI_.status == Bootstrap::DATA_MISSING)
608 eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY;
609 else
610 eErrCode = Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY;
611 break;
613 case Bootstrap::DATA_INVALID: OSL_ASSERT(false);
614 case Bootstrap::PATH_VALID:
615 addFileError(_rBuf, _rData.aBootstrapINI_.path, IS_MISSING);
616 eErrCode = Bootstrap::MISSING_BOOTSTRAP_FILE;
617 break;
619 default:
620 addUnexpectedError(_rBuf);
621 break;
623 break;
625 break;
627 default: OSL_ASSERT(false);
628 addUnexpectedError(_rBuf);
629 break;
632 return eErrCode;
634 // ---------------------------------------------------------------------------------------
635 // ---------------------------------------------------------------------------------------
636 // class Bootstrap
637 // ---------------------------------------------------------------------------------------
639 OUString Bootstrap::getProductKey()
641 OUString const csProductKeyItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_KEY));
643 OUString const sDefaultProductKey = getExecutableBaseName();
645 return data().getBootstrapValue( csProductKeyItem, sDefaultProductKey );
647 // ---------------------------------------------------------------------------------------
649 OUString Bootstrap::getProductKey(OUString const& _sDefault)
651 OUString const csProductKeyItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_KEY));
653 return data().getBootstrapValue( csProductKeyItem, _sDefault );
655 // ---------------------------------------------------------------------------------------
657 OUString Bootstrap::getProductSource(OUString const& _sDefault)
659 OUString const csProductSourceItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_PRODUCT_SOURCE));
661 OUString sProductSource;
662 // read ProductSource from version.ini (versionrc)
663 data().getVersionValue( csProductSourceItem, sProductSource, _sDefault );
664 return sProductSource;
666 // ---------------------------------------------------------------------------------------
668 OUString Bootstrap::getBuildIdData(OUString const& _sDefault)
670 OUString const csBuildIdItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_BUILDID));
672 OUString sBuildId;
673 // read buildid from version.ini (versionrc), if it doesn't exist or buildid is empty
674 if ( data().getVersionValue( csBuildIdItem, sBuildId, _sDefault ) != sal_True ||
675 sBuildId.getLength() == 0 )
676 // read buildid from bootstrap.ini (bootstraprc)
677 sBuildId = data().getBootstrapValue( csBuildIdItem, _sDefault );
678 return sBuildId;
680 // ---------------------------------------------------------------------------------------
682 OUString Bootstrap::getAllUsersValue(OUString const& _sDefault)
684 OUString const csAllUsersItem(RTL_CONSTASCII_USTRINGPARAM(SETUP_ITEM_ALLUSERS));
686 rtl::Bootstrap aData( getExecutableDirectory() + OUString( RTL_CONSTASCII_USTRINGPARAM( "/"SETUP_DATA_NAME ) ) );
687 OUString sResult;
688 aData.getFrom( csAllUsersItem, sResult, _sDefault );
689 return sResult;
691 // ---------------------------------------------------------------------------------------
693 Bootstrap::PathStatus Bootstrap::locateBaseInstallation(OUString& _rURL)
695 Impl::PathData const& aPathData = data().aBaseInstall_;
697 _rURL = aPathData.path;
698 return aPathData.status;
700 // ---------------------------------------------------------------------------------------
702 PathStatus Bootstrap::locateUserInstallation(OUString& _rURL)
704 Impl::PathData const& aPathData = data().aUserInstall_;
706 _rURL = aPathData.path;
707 return aPathData.status;
709 // ---------------------------------------------------------------------------------------
711 PathStatus Bootstrap::locateSharedData(OUString& _rURL)
713 OUString const csShareDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_SHAREDIR));
715 rtl::Bootstrap aData( data().getImplName() );
717 if ( aData.getFrom(csShareDirItem, _rURL) )
719 return checkStatusAndNormalizeURL(_rURL);
721 else
723 OUString const csShareDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_SHAREDIR));
724 return getDerivedPath(_rURL, data().aBaseInstall_, csShareDir, aData, csShareDirItem);
727 // ---------------------------------------------------------------------------------------
729 PathStatus Bootstrap::locateUserData(OUString& _rURL)
731 OUString const csUserDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERDIR));
733 rtl::Bootstrap aData( data().getImplName() );
735 if ( aData.getFrom(csUserDirItem, _rURL) )
737 return checkStatusAndNormalizeURL(_rURL);
739 else
741 OUString const csUserDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_USERDIR));
742 return getDerivedPath(_rURL, data().aUserInstall_ ,csUserDir, aData, csUserDirItem);
745 // ---------------------------------------------------------------------------------------
747 PathStatus Bootstrap::locateBootstrapFile(OUString& _rURL)
749 Impl::PathData const& aPathData = data().aBootstrapINI_;
751 _rURL = aPathData.path;
752 return aPathData.status;
754 // ---------------------------------------------------------------------------------------
756 PathStatus Bootstrap::locateVersionFile(OUString& _rURL)
758 Impl::PathData const& aPathData = data().aVersionINI_;
760 _rURL = aPathData.path;
761 return aPathData.status;
763 // ---------------------------------------------------------------------------------------
765 Bootstrap::Status Bootstrap::checkBootstrapStatus(OUString& _rDiagnosticMessage)
767 FailureCode eDummyCode(NO_FAILURE);
769 return checkBootstrapStatus(_rDiagnosticMessage,eDummyCode);
771 // ---------------------------------------------------------------------------------------
773 Bootstrap::Status Bootstrap::checkBootstrapStatus(rtl::OUString& _rDiagnosticMessage, FailureCode& _rErrCode)
775 Impl const& aData = data();
777 Status result = aData.status_;
779 // maybe do further checks here
781 OUStringBuffer sErrorBuffer;
782 if (result != DATA_OK)
783 _rErrCode = describeError(sErrorBuffer,aData);
785 else
786 _rErrCode = NO_FAILURE;
788 _rDiagnosticMessage = sErrorBuffer.makeStringAndClear();
790 return result;
793 // ---------------------------------------------------------------------------------------
794 // class Bootstrap::Impl
795 // ---------------------------------------------------------------------------------------
797 bool Bootstrap::Impl::initBaseInstallationData(rtl::Bootstrap& _rData)
799 OUString const csBaseInstallItem( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_BASEINSTALLATION) );
800 OUString const csBaseInstallDefault( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DEFAULT_BASEINSTALL) );
802 _rData.getFrom(csBaseInstallItem, aBaseInstall_.path, csBaseInstallDefault);
804 bool bResult = (PATH_EXISTS == updateStatus(aBaseInstall_));
806 implGetBootstrapFile(_rData, aBootstrapINI_);
808 return bResult;
810 // ---------------------------------------------------------------------------------------
812 bool Bootstrap::Impl::initUserInstallationData(rtl::Bootstrap& _rData)
814 OUString const csUserInstallItem( RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERINSTALLATION) );
816 if (_rData.getFrom(csUserInstallItem, aUserInstall_.path))
818 updateStatus(aUserInstall_);
820 else
822 // should we do just this
823 aUserInstall_.status = DATA_MISSING;
825 // .. or this - look for a single-user user directory ?
826 OUString const csUserDirItem(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_ITEM_USERDIR));
827 OUString sDummy;
828 // look for $BASEINSTALLATION/user only if default UserDir setting is used
829 if (! _rData.getFrom(csUserDirItem, sDummy))
831 OUString const csUserDir(RTL_CONSTASCII_USTRINGPARAM(BOOTSTRAP_DIRNAME_USERDIR));
833 if ( PATH_EXISTS == getDerivedPath(sDummy, aBaseInstall_, csUserDir, _rData, csUserDirItem) )
834 aUserInstall_ = aBaseInstall_;
838 bool bResult = (PATH_EXISTS == aUserInstall_.status);
840 implGetVersionFile(_rData, aVersionINI_);
842 return bResult;
844 // ---------------------------------------------------------------------------------------
846 Bootstrap::Status Bootstrap::Impl::initialize()
848 Bootstrap::Status result;
850 rtl::Bootstrap aData( m_aImplName );
852 if (!initBaseInstallationData(aData))
854 result = INVALID_BASE_INSTALL;
856 else if (!initUserInstallationData(aData))
858 result = INVALID_USER_INSTALL;
860 if (aUserInstall_.status >= DATA_MISSING)
862 switch (aVersionINI_.status)
864 case PATH_EXISTS:
865 case PATH_VALID:
866 result = MISSING_USER_INSTALL;
867 break;
869 case DATA_INVALID:
870 case DATA_MISSING:
871 result = INVALID_BASE_INSTALL;
872 break;
873 default:
874 break;
878 else
880 result = DATA_OK;
882 return result;
884 // ---------------------------------------------------------------------------------------
886 OUString Bootstrap::Impl::getBootstrapValue(OUString const& _sName, OUString const& _sDefault) const
888 rtl::Bootstrap aData( m_aImplName );
890 OUString sResult;
891 aData.getFrom(_sName,sResult,_sDefault);
892 return sResult;
894 // ---------------------------------------------------------------------------------------
896 sal_Bool Bootstrap::Impl::getVersionValue(OUString const& _sName, OUString& _rValue, OUString const& _sDefault) const
898 // try to open version.ini (versionrc)
899 rtl::OUString uri;
900 rtl::Bootstrap::get(
901 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("BRAND_BASE_DIR")), uri);
902 rtl::Bootstrap aData( uri +
903 OUString(RTL_CONSTASCII_USTRINGPARAM("/program/"SAL_CONFIGFILE("version"))) );
904 if ( aData.getHandle() == NULL )
905 // version.ini (versionrc) doesn't exist
906 return sal_False;
908 // read value
909 aData.getFrom(_sName,_rValue,_sDefault);
910 return sal_True;
912 // ---------------------------------------------------------------------------------------
914 } // namespace utl