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