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: */
|