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