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_features.h>
21 : #include <config_folders.h>
22 :
23 : #include "util.hxx"
24 :
25 : #include "osl/process.h"
26 : #include "osl/security.hxx"
27 : #include "osl/file.hxx"
28 : #include "osl/module.hxx"
29 : #include "rtl/byteseq.hxx"
30 : #include "rtl/ustrbuf.hxx"
31 : #include "rtl/instance.hxx"
32 : #include "salhelper/linkhelper.hxx"
33 : #include "salhelper/thread.hxx"
34 : #include "boost/noncopyable.hpp"
35 : #include "boost/scoped_array.hpp"
36 : #include "com/sun/star/uno/Sequence.hxx"
37 : #include <utility>
38 : #include <algorithm>
39 : #include <map>
40 :
41 : #if defined WNT
42 : #if defined _MSC_VER
43 : #pragma warning(push, 1)
44 : #endif
45 : #include <windows.h>
46 : #if defined _MSC_VER
47 : #pragma warning(pop)
48 : #endif
49 : #endif
50 : #include <string.h>
51 :
52 : #include "sunjre.hxx"
53 : #include "vendorlist.hxx"
54 : #include "diagnostics.h"
55 :
56 : using namespace osl;
57 : using namespace std;
58 :
59 : using ::rtl::Reference;
60 :
61 : #ifdef WNT
62 : #define HKEY_SUN_JRE L"Software\\JavaSoft\\Java Runtime Environment"
63 : #define HKEY_SUN_SDK L"Software\\JavaSoft\\Java Development Kit"
64 : #endif
65 :
66 : #ifdef UNX
67 : #if !(defined MACOSX && defined X86_64)
68 : namespace {
69 : char const *g_arJavaNames[] = {
70 : "",
71 : "j2re",
72 : "j2se",
73 : "j2sdk",
74 : "jdk",
75 : "jre",
76 : "java",
77 : "Home",
78 : "IBMJava2-ppc-142"
79 : };
80 : /* These are directory names which could contain multiple java installations.
81 : */
82 : char const *g_arCollectDirs[] = {
83 : "",
84 : #ifndef JVM_ONE_PATH_CHECK
85 : "j2re/",
86 : "j2se/",
87 : "j2sdk/",
88 : "jdk/",
89 : "jre/",
90 : "java/",
91 : #endif
92 : "jvm/"
93 : };
94 :
95 : /* These are directories in which a java installation is
96 : looked for.
97 : */
98 : char const *g_arSearchPaths[] = {
99 : #ifdef MACOSX
100 : "",
101 : "Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin",
102 : "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/"
103 : #else
104 : #ifndef JVM_ONE_PATH_CHECK
105 : "",
106 : "usr/",
107 : "usr/local/",
108 : "usr/local/IBMJava2-ppc-142",
109 : "usr/local/j2sdk1.3.1",
110 : #ifdef X86_64
111 : "usr/lib64/",
112 : #endif
113 : "usr/lib/",
114 : "usr/bin/"
115 : #else
116 : JVM_ONE_PATH_CHECK
117 : #endif
118 : #endif
119 : };
120 : }
121 : #endif
122 : #endif // UNX
123 :
124 : namespace jfw_plugin
125 : {
126 : extern VendorSupportMapEntry gVendorMap[];
127 :
128 : #if defined WNT
129 : bool getSDKInfoFromRegistry(vector<OUString> & vecHome);
130 : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome);
131 : #endif
132 :
133 : bool decodeOutput(const OString& s, OUString* out);
134 :
135 :
136 :
137 : namespace
138 : {
139 55 : OUString getLibraryLocation()
140 : {
141 55 : OUString libraryFileUrl;
142 55 : OSL_VERIFY(osl::Module::getUrlFromAddress((void *)(sal_IntPtr)getLibraryLocation, libraryFileUrl));
143 55 : return getDirFromFile(libraryFileUrl);
144 : }
145 :
146 : struct InitBootstrap
147 : {
148 55 : rtl::Bootstrap * operator()(const OUString& sIni)
149 : {
150 55 : static rtl::Bootstrap aInstance(sIni);
151 55 : return & aInstance;
152 :
153 : }
154 : };
155 :
156 : struct InitBootstrapData
157 : {
158 55 : OUString const & operator()()
159 : {
160 55 : static OUString sIni;
161 55 : OUStringBuffer buf( 255);
162 55 : buf.append( getLibraryLocation());
163 : #if HAVE_FEATURE_MACOSX_MACLIKE_APP_STRUCTURE
164 : buf.appendAscii( "/../" LIBO_ETC_FOLDER );
165 : #endif
166 55 : buf.appendAscii( SAL_CONFIGFILE("/sunjavaplugin") );
167 55 : sIni = buf.makeStringAndClear();
168 : JFW_TRACE2("[Java framework] sunjavaplugin: "
169 : "Using configuration file \n" + sIni);
170 55 : return sIni;
171 : }
172 : };
173 : }
174 :
175 118 : rtl::Bootstrap * getBootstrap()
176 : {
177 : return rtl_Instance< rtl::Bootstrap, InitBootstrap,
178 : ::osl::MutexGuard, ::osl::GetGlobalMutex,
179 : OUString, InitBootstrapData >::create(
180 118 : InitBootstrap(), ::osl::GetGlobalMutex(), InitBootstrapData());
181 : }
182 :
183 :
184 :
185 :
186 : class FileHandleGuard: private boost::noncopyable
187 : {
188 : public:
189 118 : inline FileHandleGuard(oslFileHandle & rHandle) SAL_THROW(()):
190 118 : m_rHandle(rHandle) {}
191 :
192 : inline ~FileHandleGuard() SAL_THROW(());
193 :
194 180544 : inline oslFileHandle & getHandle() SAL_THROW(()) { return m_rHandle; }
195 :
196 : private:
197 : oslFileHandle & m_rHandle;
198 : };
199 :
200 118 : inline FileHandleGuard::~FileHandleGuard() SAL_THROW(())
201 : {
202 118 : if (m_rHandle != 0)
203 : {
204 118 : if (osl_closeFile(m_rHandle) != osl_File_E_None)
205 : {
206 : OSL_FAIL("unexpected situation");
207 : }
208 : }
209 118 : }
210 :
211 :
212 59 : class FileHandleReader
213 : {
214 : public:
215 : enum Result
216 : {
217 : RESULT_OK,
218 : RESULT_EOF,
219 : RESULT_ERROR
220 : };
221 :
222 59 : inline FileHandleReader(oslFileHandle & rHandle) SAL_THROW(()):
223 59 : m_aGuard(rHandle), m_nSize(0), m_nIndex(0), m_bLf(false) {}
224 :
225 : Result readLine(OString * pLine) SAL_THROW(());
226 :
227 : private:
228 : enum { BUFFER_SIZE = 1024 };
229 :
230 : sal_Char m_aBuffer[BUFFER_SIZE];
231 : FileHandleGuard m_aGuard;
232 : int m_nSize;
233 : int m_nIndex;
234 : bool m_bLf;
235 : };
236 :
237 : FileHandleReader::Result
238 3068 : FileHandleReader::readLine(OString * pLine)
239 : SAL_THROW(())
240 : {
241 : OSL_ENSURE(pLine, "specification violation");
242 :
243 181480 : for (bool bEof = true;; bEof = false)
244 : {
245 181480 : if (m_nIndex == m_nSize)
246 : {
247 180485 : sal_uInt64 nRead = 0;
248 180485 : switch (osl_readFile(
249 180485 : m_aGuard.getHandle(), m_aBuffer, sizeof(m_aBuffer), &nRead))
250 : {
251 : case osl_File_E_PIPE: //HACK! for windows
252 0 : nRead = 0;
253 : case osl_File_E_None:
254 180485 : if (nRead == 0)
255 : {
256 59 : m_bLf = false;
257 118 : return bEof ? RESULT_EOF : RESULT_OK;
258 : }
259 180426 : m_nIndex = 0;
260 180426 : m_nSize = static_cast< int >(nRead);
261 180426 : break;
262 : case osl_File_E_INTR:
263 0 : continue;
264 :
265 : default:
266 0 : return RESULT_ERROR;
267 : }
268 : }
269 :
270 181421 : if (m_bLf && m_aBuffer[m_nIndex] == 0x0A)
271 0 : ++m_nIndex;
272 181421 : m_bLf = false;
273 :
274 181421 : int nStart = m_nIndex;
275 938976 : while (m_nIndex != m_nSize)
276 579143 : switch (m_aBuffer[m_nIndex++])
277 : {
278 : case 0x0D:
279 0 : m_bLf = true;
280 : case 0x0A:
281 6018 : *pLine += OString(m_aBuffer + nStart,
282 6018 : m_nIndex - 1 - nStart);
283 : //TODO! check for overflow, and not very efficient
284 3009 : return RESULT_OK;
285 : }
286 :
287 178412 : *pLine += OString(m_aBuffer + nStart, m_nIndex - nStart);
288 : //TODO! check for overflow, and not very efficient
289 178412 : }
290 : }
291 :
292 : class AsynchReader: public salhelper::Thread
293 : {
294 : size_t m_nDataSize;
295 : boost::scoped_array<sal_Char> m_arData;
296 :
297 : bool m_bError;
298 : bool m_bDone;
299 : FileHandleGuard m_aGuard;
300 :
301 118 : virtual ~AsynchReader() {}
302 :
303 : void execute() SAL_OVERRIDE;
304 : public:
305 :
306 : AsynchReader(oslFileHandle & rHandle);
307 :
308 : /** only call this function after this thread has finished.
309 :
310 : That is, call join on this instance and then call getData.
311 :
312 : */
313 : OString getData();
314 : };
315 :
316 59 : AsynchReader::AsynchReader(oslFileHandle & rHandle):
317 : Thread("jvmfwkAsyncReader"), m_nDataSize(0), m_bError(false),
318 59 : m_bDone(false), m_aGuard(rHandle)
319 : {
320 59 : }
321 :
322 0 : OString AsynchReader::getData()
323 : {
324 0 : return OString(m_arData.get(), m_nDataSize);
325 : }
326 :
327 59 : void AsynchReader::execute()
328 : {
329 59 : const sal_uInt64 BUFFER_SIZE = 4096;
330 : sal_Char aBuffer[BUFFER_SIZE];
331 : while (true)
332 : {
333 : sal_uInt64 nRead;
334 : //the function blocks until something could be read or the pipe closed.
335 59 : switch (osl_readFile(
336 59 : m_aGuard.getHandle(), aBuffer, BUFFER_SIZE, &nRead))
337 : {
338 : case osl_File_E_PIPE: //HACK! for windows
339 0 : nRead = 0;
340 : case osl_File_E_None:
341 59 : break;
342 : default:
343 0 : m_bError = true;
344 59 : return;
345 : }
346 :
347 59 : if (nRead == 0)
348 : {
349 59 : m_bDone = true;
350 118 : break;
351 : }
352 0 : else if (nRead <= BUFFER_SIZE)
353 : {
354 : //Save the data we have in m_arData into a temporary array
355 0 : boost::scoped_array<sal_Char> arTmp( new sal_Char[m_nDataSize]);
356 0 : memcpy(arTmp.get(), m_arData.get(), m_nDataSize);
357 : //Enlarge m_arData to hold the newly read data
358 0 : m_arData.reset(new sal_Char[(size_t)(m_nDataSize + nRead)]);
359 : //Copy back the data that was already in m_arData
360 0 : memcpy(m_arData.get(), arTmp.get(), m_nDataSize);
361 : //Add the newly read data to m_arData
362 0 : memcpy(m_arData.get() + m_nDataSize, aBuffer, (size_t) nRead);
363 0 : m_nDataSize += (size_t) nRead;
364 : }
365 0 : }
366 : }
367 :
368 118 : static bool isEnvVarSetToOne(const OUString &aVar)
369 : {
370 118 : OUString aValue;
371 118 : getBootstrap()->getFrom(aVar, aValue);
372 118 : return aValue == "1";
373 : }
374 :
375 59 : bool getJavaProps(const OUString & exePath,
376 : #ifdef JVM_ONE_PATH_CHECK
377 : const OUString & homePath,
378 : #endif
379 : std::vector<std::pair<OUString, OUString> >& props,
380 : bool * bProcessRun)
381 : {
382 59 : bool ret = false;
383 :
384 : OSL_ASSERT(!exePath.isEmpty());
385 59 : OUString usStartDir;
386 : //We need to set the CLASSPATH in case the office is started from
387 : //a different directory. The JREProperties.class is expected to reside
388 : //next to the plugin.
389 118 : OUString sThisLib;
390 59 : if (osl_getModuleURLFromAddress((void *) (sal_IntPtr)& getJavaProps,
391 59 : & sThisLib.pData) == sal_False)
392 0 : return false;
393 59 : sThisLib = getDirFromFile(sThisLib);
394 118 : OUString sClassPath;
395 59 : if (osl_getSystemPathFromFileURL(sThisLib.pData, & sClassPath.pData)
396 : != osl_File_E_None)
397 0 : return false;
398 :
399 : //check if we shall examine a Java for accessibility support
400 : //If the bootstrap variable is "1" then we pass the argument
401 : //"noaccessibility" to JREProperties.class. This will prevent
402 : //that it calls java.awt.Toolkit.getDefaultToolkit();
403 59 : bool bNoAccessibility = isEnvVarSetToOne("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY");
404 :
405 : //prepare the arguments
406 59 : sal_Int32 cArgs = 3;
407 118 : OUString arg1 = "-classpath";// + sClassPath;
408 118 : OUString arg2 = sClassPath;
409 118 : OUString arg3("JREProperties");
410 118 : OUString arg4 = "noaccessibility";
411 59 : rtl_uString *args[4] = {arg1.pData, arg2.pData, arg3.pData};
412 :
413 : #ifdef UNX
414 : // Java is no longer required for a11y - we use atk directly.
415 59 : bNoAccessibility = !isEnvVarSetToOne("JFW_PLUGIN_FORCE_ACCESSIBILITY");
416 : #endif
417 :
418 : // Only add the fourth param if the bootstrap parameter is set.
419 59 : if (bNoAccessibility)
420 : {
421 59 : args[3] = arg4.pData;
422 59 : cArgs = 4;
423 : }
424 :
425 59 : oslProcess javaProcess= 0;
426 59 : oslFileHandle fileOut= 0;
427 59 : oslFileHandle fileErr= 0;
428 :
429 118 : FileHandleReader stdoutReader(fileOut);
430 118 : rtl::Reference< AsynchReader > stderrReader(new AsynchReader(fileErr));
431 :
432 : JFW_TRACE2("\n[Java framework] Executing: " + exePath + ".\n");
433 : oslProcessError procErr =
434 : osl_executeProcess_WithRedirectedIO( exePath.pData,//usExe.pData,
435 : args,
436 : cArgs, //sal_uInt32 nArguments,
437 : osl_Process_HIDDEN, //oslProcessOption Options,
438 : NULL, //oslSecurity Security,
439 : usStartDir.pData,//usStartDir.pData,//usWorkDir.pData, //rtl_uString *strWorkDir,
440 : NULL, //rtl_uString *strEnvironment[],
441 : 0, // sal_uInt32 nEnvironmentVars,
442 : &javaProcess, //oslProcess *pProcess,
443 : NULL,//oslFileHandle *pChildInputWrite,
444 : &fileOut,//oslFileHandle *pChildOutputRead,
445 59 : &fileErr);//oslFileHandle *pChildErrorRead);
446 :
447 59 : if( procErr != osl_Process_E_None)
448 : {
449 : JFW_TRACE2("[Java framework] Execution failed. \n");
450 0 : *bProcessRun = false;
451 0 : return ret;
452 : }
453 : else
454 : {
455 : JFW_TRACE2("[Java framework] Java executed successfully.\n");
456 59 : *bProcessRun = true;
457 : }
458 :
459 : //Start asynchronous reading (different thread) of error stream
460 59 : stderrReader->launch();
461 :
462 : //Use this thread to read output stream
463 59 : FileHandleReader::Result rs = FileHandleReader::RESULT_OK;
464 : while (true)
465 : {
466 3068 : OString aLine;
467 3068 : rs = stdoutReader.readLine( & aLine);
468 3068 : if (rs != FileHandleReader::RESULT_OK)
469 59 : break;
470 6018 : OUString sLine;
471 3009 : if (!decodeOutput(aLine, &sLine))
472 0 : continue;
473 : JFW_TRACE2("[Java framework]:\" " << sLine << " \".\n");
474 3009 : sLine = sLine.trim();
475 3009 : if (sLine.isEmpty())
476 0 : continue;
477 : //The JREProperties class writes key value pairs, separated by '='
478 3009 : sal_Int32 index = sLine.indexOf('=', 0);
479 : OSL_ASSERT(index != -1);
480 6018 : OUString sKey = sLine.copy(0, index);
481 6018 : OUString sVal = sLine.copy(index + 1);
482 :
483 : #ifdef JVM_ONE_PATH_CHECK
484 : //replace absolute path by linux distro link
485 : OUString sHomeProperty("java.home");
486 : if(sHomeProperty.equals(sKey))
487 : {
488 : sVal = homePath + "/jre";
489 : }
490 : #endif
491 :
492 3009 : props.push_back(std::make_pair(sKey, sVal));
493 3009 : }
494 :
495 59 : if (rs != FileHandleReader::RESULT_ERROR && !props.empty())
496 59 : ret = true;
497 :
498 : //process error stream data
499 59 : stderrReader->join();
500 : JFW_TRACE2("[Java framework] Java wrote to stderr:\" "
501 : << stderrReader->getData().getStr() << " \".\n");
502 :
503 59 : TimeValue waitMax= {5 ,0};
504 59 : procErr = osl_joinProcessWithTimeout(javaProcess, &waitMax);
505 : OSL_ASSERT(procErr == osl_Process_E_None);
506 59 : osl_freeProcessHandle(javaProcess);
507 118 : return ret;
508 : }
509 :
510 : /* converts the properties printed by JREProperties.class into
511 : readable strings. The strings are encoded as integer values separated
512 : by spaces.
513 : */
514 3009 : bool decodeOutput(const OString& s, OUString* out)
515 : {
516 : OSL_ASSERT(out != 0);
517 3009 : OUStringBuffer buff(512);
518 3009 : sal_Int32 nIndex = 0;
519 166259 : do
520 : {
521 166259 : OString aToken = s.getToken( 0, ' ', nIndex );
522 166259 : if (!aToken.isEmpty())
523 : {
524 576134 : for (sal_Int32 i = 0; i < aToken.getLength(); ++i)
525 : {
526 412884 : if (aToken[i] < '0' || aToken[i] > '9')
527 0 : return false;
528 : }
529 163250 : sal_Unicode value = (sal_Unicode)(aToken.toInt32());
530 163250 : buff.append(value);
531 166259 : }
532 166259 : } while (nIndex >= 0);
533 :
534 3009 : *out = buff.makeStringAndClear();
535 3009 : return true;
536 : }
537 :
538 :
539 : #if defined WNT
540 : void createJavaInfoFromWinReg(std::vector<rtl::Reference<VendorBase> > & vecInfos)
541 : {
542 : // Get Java s from registry
543 : std::vector<OUString> vecJavaHome;
544 : if(getSDKInfoFromRegistry(vecJavaHome))
545 : {
546 : // create impl objects
547 : typedef std::vector<OUString>::iterator ItHome;
548 : for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
549 : it_home++)
550 : {
551 : getJREInfoByPath(*it_home, vecInfos);
552 : }
553 : }
554 :
555 : vecJavaHome.clear();
556 : if(getJREInfoFromRegistry(vecJavaHome))
557 : {
558 : typedef std::vector<OUString>::iterator ItHome;
559 : for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
560 : it_home++)
561 : {
562 : getJREInfoByPath(*it_home, vecInfos);
563 : }
564 : }
565 : }
566 :
567 :
568 : bool getJavaInfoFromRegistry(const wchar_t* szRegKey,
569 : vector<OUString>& vecJavaHome)
570 : {
571 : HKEY hRoot;
572 : if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ENUMERATE_SUB_KEYS, &hRoot)
573 : == ERROR_SUCCESS)
574 : {
575 : DWORD dwIndex = 0;
576 : const DWORD BUFFSIZE = 1024;
577 : wchar_t bufVersion[BUFFSIZE];
578 : DWORD nNameLen = BUFFSIZE;
579 : FILETIME fileTime;
580 : nNameLen = sizeof(bufVersion);
581 :
582 : // Iterate over all subkeys of HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment
583 : while (RegEnumKeyExW(hRoot, dwIndex, bufVersion, &nNameLen, NULL, NULL, NULL, &fileTime) != ERROR_NO_MORE_ITEMS)
584 : {
585 : HKEY hKey;
586 : // Open a Java Runtime Environment sub key, e.g. "1.4.0"
587 : if (RegOpenKeyExW(hRoot, bufVersion, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
588 : {
589 : DWORD dwType;
590 : DWORD dwTmpPathLen= 0;
591 : // Get the path to the JavaHome every JRE entry
592 : // Find out how long the string for JavaHome is and allocate memory to hold the path
593 : if( RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, NULL, &dwTmpPathLen)== ERROR_SUCCESS)
594 : {
595 : char* szTmpPath= (char *) malloc( dwTmpPathLen);
596 : // Get the path for the runtime lib
597 : if(RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, (unsigned char*) szTmpPath, &dwTmpPathLen) == ERROR_SUCCESS)
598 : {
599 : // There can be several version entries refering with the same JavaHome,e.g 1.4 and 1.4.1
600 : OUString usHome((sal_Unicode*) szTmpPath);
601 : // check if there is already an entry with the same JavaHomeruntime lib
602 : // if so, we use the one with the more accurate version
603 : bool bAppend= true;
604 : OUString usHomeUrl;
605 : if (osl_getFileURLFromSystemPath(usHome.pData, & usHomeUrl.pData) ==
606 : osl_File_E_None)
607 : {
608 : //iterate over the vector with java home strings
609 : typedef vector<OUString>::iterator ItHome;
610 : for(ItHome itHome= vecJavaHome.begin();
611 : itHome != vecJavaHome.end(); itHome++)
612 : {
613 : if(usHomeUrl.equals(*itHome))
614 : {
615 : bAppend= false;
616 : break;
617 : }
618 : }
619 : // Save the home dir
620 : if(bAppend)
621 : {
622 : vecJavaHome.push_back(usHomeUrl);
623 : }
624 : }
625 : }
626 : free( szTmpPath);
627 : RegCloseKey(hKey);
628 : }
629 : }
630 : dwIndex ++;
631 : nNameLen = BUFFSIZE;
632 : }
633 : RegCloseKey(hRoot);
634 : }
635 : return true;
636 : }
637 :
638 :
639 :
640 : bool getSDKInfoFromRegistry(vector<OUString> & vecHome)
641 : {
642 : return getJavaInfoFromRegistry(HKEY_SUN_SDK, vecHome);
643 : }
644 :
645 : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome)
646 : {
647 : return getJavaInfoFromRegistry(HKEY_SUN_JRE, vecJavaHome);
648 : }
649 :
650 : #endif // WNT
651 :
652 8 : void bubbleSortVersion(vector<rtl::Reference<VendorBase> >& vec)
653 : {
654 8 : if(vec.empty())
655 8 : return;
656 8 : int size= vec.size() - 1;
657 8 : int cIter= 0;
658 : // sort for version
659 8 : for(int i= 0; i < size; i++)
660 : {
661 0 : for(int j= size; j > 0 + cIter; j--)
662 : {
663 0 : rtl::Reference<VendorBase>& cur= vec.at(j);
664 0 : rtl::Reference<VendorBase>& next= vec.at(j-1);
665 :
666 0 : int nCmp = 0;
667 : // comparing invalid SunVersion s is possible, they will be less than a
668 : // valid version
669 :
670 : //check if version of current is recognized, by comparing it with itself
671 : try
672 : {
673 0 : cur->compareVersions(cur->getVersion());
674 : }
675 0 : catch (MalformedVersionException &)
676 : {
677 0 : nCmp = -1; // current < next
678 : }
679 : //The version of cur is valid, now compare with the second version
680 0 : if (nCmp == 0)
681 : {
682 : try
683 : {
684 0 : nCmp = cur->compareVersions(next->getVersion());
685 : }
686 0 : catch (MalformedVersionException & )
687 : {
688 : //The second version is invalid, therefor it is regardes less.
689 0 : nCmp = 1;
690 : }
691 : }
692 0 : if(nCmp == 1) // cur > next
693 : {
694 0 : rtl::Reference<VendorBase> less = next;
695 0 : vec.at(j-1)= cur;
696 0 : vec.at(j)= less;
697 : }
698 : }
699 0 : ++cIter;
700 : }
701 : }
702 :
703 :
704 64 : bool getJREInfoFromBinPath(
705 : const OUString& path, vector<rtl::Reference<VendorBase> > & vecInfos)
706 : {
707 : // file:///c:/jre/bin
708 : //map: jre/bin/java.exe
709 64 : bool ret = false;
710 :
711 992 : for ( sal_Int32 pos = 0;
712 496 : gVendorMap[pos].sVendorName != NULL; ++pos )
713 : {
714 448 : vector<OUString> vecPaths;
715 448 : getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
716 :
717 448 : int size = 0;
718 448 : char const* const* arExePaths = (*pFunc)(&size);
719 448 : vecPaths = getVectorFromCharArray(arExePaths, size);
720 :
721 : //make sure argument path does not end with '/'
722 880 : OUString sBinPath = path;
723 448 : if (path.endsWith("/"))
724 0 : sBinPath = path.copy(0, path.getLength() - 1);
725 :
726 : typedef vector<OUString>::const_iterator c_it;
727 1696 : for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
728 : {
729 : //the map contains e.g. jre/bin/java.exe
730 : //get the directory where the executable is contained
731 1264 : OUString sHome;
732 1264 : sal_Int32 index = i->lastIndexOf('/');
733 1264 : if (index == -1)
734 : {
735 : //map contained only : "java.exe, then the argument
736 : //path is already the home directory
737 304 : sHome = sBinPath;
738 : }
739 : else
740 : {
741 : // jre/bin/jre -> jre/bin
742 960 : OUString sMapPath(i->getStr(), index);
743 960 : index = sBinPath.lastIndexOf(sMapPath);
744 960 : if (index != -1
745 480 : && (index + sMapPath.getLength() == sBinPath.getLength())
746 1440 : && sBinPath[index - 1] == '/')
747 : {
748 288 : sHome = sBinPath.copy(index - 1);
749 960 : }
750 : }
751 1264 : if (!sHome.isEmpty())
752 : {
753 592 : ret = getJREInfoByPath(sHome, vecInfos);
754 592 : if (ret)
755 16 : break;
756 : }
757 1248 : }
758 448 : if (ret)
759 16 : break;
760 432 : }
761 64 : return ret;
762 : }
763 :
764 8 : vector<Reference<VendorBase> > getAllJREInfos()
765 : {
766 8 : vector<Reference<VendorBase> > vecInfos;
767 :
768 : #if defined WNT
769 : // Get Javas from the registry
770 : createJavaInfoFromWinReg(vecInfos);
771 : #endif // WNT
772 :
773 : #ifndef JVM_ONE_PATH_CHECK
774 8 : createJavaInfoFromJavaHome(vecInfos);
775 : //this function should be called after createJavaInfoDirScan.
776 : //Otherwise in SDKs Java may be started twice
777 8 : createJavaInfoFromPath(vecInfos);
778 : #endif
779 :
780 : #ifdef UNX
781 8 : createJavaInfoDirScan(vecInfos);
782 : #endif
783 :
784 8 : bubbleSortVersion(vecInfos);
785 8 : return vecInfos;
786 : }
787 :
788 :
789 3089 : vector<OUString> getVectorFromCharArray(char const * const * ar, int size)
790 : {
791 3089 : vector<OUString> vec;
792 12154 : for( int i = 0; i < size; i++)
793 : {
794 9065 : OUString s(ar[i], strlen(ar[i]), RTL_TEXTENCODING_UTF8);
795 9065 : vec.push_back(s);
796 9065 : }
797 3089 : return vec;
798 : }
799 744 : bool getJREInfoByPath(const OUString& path,
800 : std::vector<rtl::Reference<VendorBase> > & vecInfos)
801 : {
802 744 : bool ret = false;
803 :
804 744 : rtl::Reference<VendorBase> aInfo = getJREInfoByPath(path);
805 744 : if (aInfo.is())
806 : {
807 128 : ret = true;
808 : vector<rtl::Reference<VendorBase> >::const_iterator it_impl= std::find_if(
809 128 : vecInfos.begin(),vecInfos.end(), InfoFindSame(aInfo->getHome()));
810 128 : if(it_impl == vecInfos.end())
811 : {
812 8 : vecInfos.push_back(aInfo);
813 : }
814 : }
815 744 : return ret;
816 : }
817 :
818 : /** Checks if the path is a directory. Links are resolved.
819 : In case of an error the returned string has the length 0.
820 : Otherwise the returned string is the "resolved" file URL.
821 : */
822 846 : OUString resolveDirPath(const OUString & path)
823 : {
824 846 : OUString ret;
825 : salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
826 1692 : osl_FileStatus_Mask_FileURL);
827 846 : if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
828 : {
829 : //check if this is a directory
830 510 : if (aResolver.m_aStatus.getFileType() == FileStatus::Directory)
831 : {
832 : #ifndef JVM_ONE_PATH_CHECK
833 502 : ret = aResolver.m_aStatus.getFileURL();
834 : #else
835 : ret = path;
836 : #endif
837 : }
838 : }
839 1692 : return ret;
840 : }
841 : /** Checks if the path is a file. If it is a link to a file than
842 : it is resolved.
843 : */
844 7218 : OUString resolveFilePath(const OUString & path)
845 : {
846 7218 : OUString ret;
847 : salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
848 14436 : osl_FileStatus_Mask_FileURL);
849 7218 : if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
850 : {
851 : //check if this is a file
852 91 : if (aResolver.m_aStatus.getFileType() == FileStatus::Regular)
853 : {
854 : #ifndef JVM_ONE_PATH_CHECK
855 75 : ret = aResolver.m_aStatus.getFileURL();
856 : #else
857 : ret = path;
858 : #endif
859 : }
860 : }
861 14436 : return ret;
862 : }
863 :
864 846 : rtl::Reference<VendorBase> getJREInfoByPath(
865 : const OUString& path)
866 : {
867 846 : rtl::Reference<VendorBase> ret;
868 846 : static vector<OUString> vecBadPaths;
869 :
870 846 : static map<OUString, rtl::Reference<VendorBase> > mapJREs;
871 : typedef map<OUString, rtl::Reference<VendorBase> >::const_iterator MapIt;
872 : typedef map<OUString, rtl::Reference<VendorBase> > MAPJRE;
873 1692 : OUString sFilePath;
874 : typedef vector<OUString>::const_iterator cit_path;
875 1692 : vector<pair<OUString, OUString> > props;
876 :
877 1692 : OUString sResolvedDir = resolveDirPath(path);
878 : // If this path is invalid then there is no chance to find a JRE here
879 846 : if (sResolvedDir.isEmpty())
880 344 : return 0;
881 :
882 : //check if the directory path is good, that is a JRE was already recognized.
883 : //Then we need not detect it again
884 : //For example, a sun JKD contains <jdk>/bin/java and <jdk>/jre/bin/java.
885 : //When <jdk>/bin/java has been found then we need not find <jdk>/jre/bin/java.
886 : //Otherwise we would execute java two times for evers JDK found.
887 : MapIt entry2 = find_if(mapJREs.begin(), mapJREs.end(),
888 502 : SameOrSubDirJREMap(sResolvedDir));
889 502 : if (entry2 != mapJREs.end())
890 : {
891 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
892 : + SAL_DLLEXTENSION + ": "
893 : + "JRE found again (detected before): " + sResolvedDir
894 : + ".\n");
895 155 : return entry2->second;
896 : }
897 :
898 5590 : for ( sal_Int32 pos = 0;
899 2795 : gVendorMap[pos].sVendorName != NULL; ++pos )
900 : {
901 2523 : vector<OUString> vecPaths;
902 2523 : getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
903 :
904 2523 : int size = 0;
905 2523 : char const* const* arExePaths = (*pFunc)(&size);
906 2523 : vecPaths = getVectorFromCharArray(arExePaths, size);
907 :
908 2523 : bool bBreak = false;
909 : typedef vector<OUString>::const_iterator c_it;
910 9666 : for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
911 : {
912 : //if the path is a link, then resolve it
913 : //check if the executable exists at all
914 :
915 : //path can be only "file:///". Then do not append a '/'
916 : //sizeof counts the terminating 0
917 7218 : OUString sFullPath;
918 7218 : if (path.getLength() == sizeof("file:///") - 1)
919 16 : sFullPath = sResolvedDir + (*i);
920 : else
921 28808 : sFullPath = sResolvedDir +
922 36010 : OUString("/") + (*i);
923 :
924 :
925 7218 : sFilePath = resolveFilePath(sFullPath);
926 :
927 7218 : if (sFilePath.isEmpty())
928 : {
929 : //The file path (to java exe) is not valid
930 7143 : cit_path ifull = find(vecBadPaths.begin(), vecBadPaths.end(), sFullPath);
931 7143 : if (ifull == vecBadPaths.end())
932 439 : vecBadPaths.push_back(sFullPath);
933 7143 : continue;
934 : }
935 :
936 75 : cit_path ifile = find(vecBadPaths.begin(), vecBadPaths.end(), sFilePath);
937 75 : if (ifile != vecBadPaths.end())
938 0 : continue;
939 :
940 75 : MapIt entry = mapJREs.find(sFilePath);
941 75 : if (entry != mapJREs.end())
942 : {
943 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
944 : + SAL_DLLEXTENSION + ": "
945 : + "JRE found again (detected before): " + sFilePath
946 : + ".\n");
947 :
948 16 : return entry->second;
949 : }
950 :
951 59 : bool bProcessRun= false;
952 59 : if (getJavaProps(sFilePath,
953 : #ifdef JVM_ONE_PATH_CHECK
954 : sResolvedDir,
955 : #endif
956 59 : props, & bProcessRun) == false)
957 : {
958 : //The java executable could not be run or the system properties
959 : //could not be retrieved. We can assume that this java is corrupt.
960 0 : vecBadPaths.push_back(sFilePath);
961 : //If there was a java executable, that could be run but we did not get
962 : //the system properties, then we also assume that the whole Java installation
963 : //does not work. In a jdk there are two executables. One in jdk/bin and the other
964 : //in jdk/jre/bin. We do not search any further, because we assume that if one java
965 : //does not work then the other does not work as well. This saves us to run java
966 : //again which is quite costly.
967 0 : if (bProcessRun == true)
968 : {
969 : // 1.3.1 special treatment: jdk/bin/java and /jdk/jre/bin/java are links to
970 : //a script, named .java_wrapper. The script starts jdk/bin/sparc/native_threads/java
971 : //or jdk/jre/bin/sparc/native_threads/java. The script uses the name with which it was
972 : //invoked to build the path to the executable. It we start the script directy as .java_wrapper
973 : //then it tries to start a jdk/.../native_threads/.java_wrapper. Therefore the link, which
974 : //is named java, must be used to start the script.
975 : getJavaProps(sFullPath,
976 : #ifdef JVM_ONE_PATH_CHECK
977 : sResolvedDir,
978 : #endif
979 0 : props, & bProcessRun);
980 : // Either we found a working 1.3.1
981 : //Or the java is broken. In both cases we stop searchin under this "root" directory
982 0 : bBreak = true;
983 0 : break;
984 : }
985 : //sFilePath is no working java executable. We continue with another possible
986 : //path.
987 : else
988 : {
989 0 : continue;
990 : }
991 : }
992 : //sFilePath is a java and we could get the system properties. We proceed with this
993 : //java.
994 : else
995 : {
996 59 : bBreak = true;
997 59 : break;
998 : }
999 0 : }
1000 2507 : if (bBreak)
1001 59 : break;
1002 2448 : }
1003 :
1004 331 : if (props.empty())
1005 272 : return rtl::Reference<VendorBase>();
1006 :
1007 : //find java.vendor property
1008 : typedef vector<pair<OUString, OUString> >::const_iterator c_ip;
1009 118 : OUString sVendor("java.vendor");
1010 118 : OUString sVendorName;
1011 :
1012 2714 : for (c_ip i = props.begin(); i != props.end(); ++i)
1013 : {
1014 2714 : if (sVendor.equals(i->first))
1015 : {
1016 59 : sVendorName = i->second;
1017 59 : break;
1018 : }
1019 : }
1020 :
1021 59 : if (!sVendorName.isEmpty())
1022 : {
1023 : //find the creator func for the respective vendor name
1024 236 : for ( sal_Int32 c = 0;
1025 118 : gVendorMap[c].sVendorName != NULL; ++c )
1026 : {
1027 118 : OUString sNameMap(gVendorMap[c].sVendorName, strlen(gVendorMap[c].sVendorName),
1028 118 : RTL_TEXTENCODING_ASCII_US);
1029 118 : if (sNameMap.equals(sVendorName))
1030 : {
1031 59 : ret = createInstance(gVendorMap[c].createFunc, props);
1032 59 : break;
1033 : }
1034 59 : }
1035 : }
1036 59 : if (!ret.is())
1037 0 : vecBadPaths.push_back(sFilePath);
1038 : else
1039 : {
1040 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
1041 : + SAL_DLLEXTENSION + ": "
1042 : + "Found JRE: " + sResolvedDir
1043 : + " \n at: " + path + ".\n");
1044 :
1045 59 : mapJREs.insert(MAPJRE::value_type(sResolvedDir, ret));
1046 59 : mapJREs.insert(MAPJRE::value_type(sFilePath, ret));
1047 : }
1048 :
1049 905 : return ret;
1050 : }
1051 :
1052 59 : Reference<VendorBase> createInstance(createInstance_func pFunc,
1053 : vector<pair<OUString, OUString> > properties)
1054 : {
1055 :
1056 59 : Reference<VendorBase> aBase = (*pFunc)();
1057 59 : if (aBase.is())
1058 : {
1059 59 : if (aBase->initialize(properties) == false)
1060 0 : aBase = 0;
1061 : }
1062 59 : return aBase;
1063 : }
1064 :
1065 114 : inline OUString getDirFromFile(const OUString& usFilePath)
1066 : {
1067 114 : sal_Int32 index = usFilePath.lastIndexOf('/');
1068 114 : return usFilePath.copy(0, index);
1069 : }
1070 :
1071 8 : void createJavaInfoFromPath(vector<rtl::Reference<VendorBase> >& vecInfos)
1072 : {
1073 : // Get Java from PATH environment variable
1074 8 : static OUString sCurDir(".");
1075 8 : static OUString sParentDir("..");
1076 8 : char *szPath= getenv("PATH");
1077 8 : if(szPath)
1078 : {
1079 8 : OUString usAllPath(szPath, strlen(szPath), osl_getThreadTextEncoding());
1080 8 : sal_Int32 nIndex = 0;
1081 64 : do
1082 : {
1083 64 : OUString usToken = usAllPath.getToken( 0, SAL_PATHSEPARATOR, nIndex );
1084 128 : OUString usTokenUrl;
1085 64 : if(File::getFileURLFromSystemPath(usToken, usTokenUrl) == File::E_None)
1086 : {
1087 64 : if(!usTokenUrl.isEmpty())
1088 : {
1089 64 : OUString usBin;
1090 : // "."
1091 64 : if(usTokenUrl.equals(sCurDir))
1092 : {
1093 8 : OUString usWorkDirUrl;
1094 8 : if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDirUrl.pData))
1095 8 : usBin= usWorkDirUrl;
1096 : }
1097 : // ".."
1098 56 : else if(usTokenUrl.equals(sParentDir))
1099 : {
1100 0 : OUString usWorkDir;
1101 0 : if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDir.pData))
1102 0 : usBin= getDirFromFile(usWorkDir);
1103 : }
1104 : else
1105 : {
1106 56 : usBin = usTokenUrl;
1107 : }
1108 64 : if(!usBin.isEmpty())
1109 : {
1110 64 : getJREInfoFromBinPath(usBin, vecInfos);
1111 64 : }
1112 : }
1113 64 : }
1114 : }
1115 72 : while ( nIndex >= 0 );
1116 : }
1117 8 : }
1118 :
1119 8 : void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos)
1120 : {
1121 : // Get Java from JAVA_HOME environment
1122 8 : char *szJavaHome= getenv("JAVA_HOME");
1123 8 : if(szJavaHome)
1124 : {
1125 8 : OUString sHome(szJavaHome,strlen(szJavaHome),osl_getThreadTextEncoding());
1126 16 : OUString sHomeUrl;
1127 8 : if(File::getFileURLFromSystemPath(sHome, sHomeUrl) == File::E_None)
1128 : {
1129 8 : getJREInfoByPath(sHomeUrl, vecInfos);
1130 8 : }
1131 : }
1132 8 : }
1133 :
1134 59 : bool makeDriveLetterSame(OUString * fileURL)
1135 : {
1136 59 : bool ret = false;
1137 59 : DirectoryItem item;
1138 59 : if (DirectoryItem::get(*fileURL, item) == File::E_None)
1139 : {
1140 59 : FileStatus status(osl_FileStatus_Mask_FileURL);
1141 59 : if (item.getFileStatus(status) == File::E_None)
1142 : {
1143 59 : *fileURL = status.getFileURL();
1144 59 : ret = true;
1145 59 : }
1146 : }
1147 59 : return ret;
1148 : }
1149 :
1150 : #ifdef UNX
1151 : #ifdef SOLARIS
1152 :
1153 : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
1154 : {
1155 : JFW_TRACE2("\n[Java framework] Checking \"/usr/jdk/latest\"\n");
1156 : getJREInfoByPath("file:////usr/jdk/latest", vecInfos);
1157 : }
1158 :
1159 : #elif defined MACOSX && defined X86_64
1160 :
1161 : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
1162 : {
1163 : // Oracle Java 7
1164 : getJREInfoByPath("file:///Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home", vecInfos);
1165 : }
1166 :
1167 : #else
1168 8 : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
1169 : {
1170 : OUString excMessage = "[Java framework] sunjavaplugin: "
1171 8 : "Error in function createJavaInfoDirScan in util.cxx.";
1172 8 : int cJavaNames= sizeof(g_arJavaNames) / sizeof(char*);
1173 16 : boost::scoped_array<OUString> sarJavaNames(new OUString[cJavaNames]);
1174 8 : OUString *arNames = sarJavaNames.get();
1175 80 : for(int i= 0; i < cJavaNames; i++)
1176 144 : arNames[i] = OUString(g_arJavaNames[i], strlen(g_arJavaNames[i]),
1177 72 : RTL_TEXTENCODING_UTF8);
1178 :
1179 8 : int cSearchPaths= sizeof(g_arSearchPaths) / sizeof(char*);
1180 16 : boost::scoped_array<OUString> sarPathNames(new OUString[cSearchPaths]);
1181 8 : OUString *arPaths = sarPathNames.get();
1182 64 : for(int c = 0; c < cSearchPaths; c++)
1183 112 : arPaths[c] = OUString(g_arSearchPaths[c], strlen(g_arSearchPaths[c]),
1184 56 : RTL_TEXTENCODING_UTF8);
1185 :
1186 8 : int cCollectDirs = sizeof(g_arCollectDirs) / sizeof(char*);
1187 16 : boost::scoped_array<OUString> sarCollectDirs(new OUString[cCollectDirs]);
1188 8 : OUString *arCollectDirs = sarCollectDirs.get();
1189 72 : for(int d = 0; d < cCollectDirs; d++)
1190 128 : arCollectDirs[d] = OUString(g_arCollectDirs[d], strlen(g_arCollectDirs[d]),
1191 64 : RTL_TEXTENCODING_UTF8);
1192 :
1193 :
1194 :
1195 16 : OUString usFile("file:///");
1196 64 : for( int ii = 0; ii < cSearchPaths; ii ++)
1197 : {
1198 56 : OUString usDir1(usFile + arPaths[ii]);
1199 112 : DirectoryItem item;
1200 56 : if(DirectoryItem::get(usDir1, item) == File::E_None)
1201 : {
1202 360 : for(int j= 0; j < cCollectDirs; j++)
1203 : {
1204 320 : OUString usDir2(usDir1 + arCollectDirs[j]);
1205 : // prevent that we scan the whole /usr, /usr/lib, etc directories
1206 320 : if (!arCollectDirs[j].isEmpty())
1207 : {
1208 : //usr/java/xxx
1209 : //Examin every subdirectory
1210 280 : Directory aCollectionDir(usDir2);
1211 :
1212 280 : Directory::RC openErr = aCollectionDir.open();
1213 280 : switch (openErr)
1214 : {
1215 : case File::E_None:
1216 16 : break;
1217 : case File::E_NOENT:
1218 : case File::E_NOTDIR:
1219 264 : continue;
1220 : case File::E_ACCES:
1221 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ")
1222 : + "Could not read directory " + usDir2
1223 : + " because of missing access rights.");
1224 0 : continue;
1225 : default:
1226 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ")
1227 : + "Could not read directory "
1228 : + usDir2 + ". Osl file error: "
1229 : + OUString::number(openErr));
1230 0 : continue;
1231 : }
1232 :
1233 16 : DirectoryItem curIt;
1234 16 : File::RC errNext = File::E_None;
1235 120 : while( (errNext = aCollectionDir.getNextItem(curIt)) == File::E_None)
1236 : {
1237 88 : FileStatus aStatus(osl_FileStatus_Mask_FileURL);
1238 88 : File::RC errStatus = File::E_None;
1239 88 : if ((errStatus = curIt.getFileStatus(aStatus)) != File::E_None)
1240 : {
1241 : JFW_TRACE2(excMessage + "getFileStatus failed with error "
1242 : + OUString::number(errStatus));
1243 0 : continue;
1244 : }
1245 : JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ") +
1246 : "Checking if directory: " + aStatus.getFileURL() +
1247 : " is a Java. \n");
1248 :
1249 88 : getJREInfoByPath(aStatus.getFileURL(),vecInfos);
1250 88 : }
1251 :
1252 : JFW_ENSURE(errNext == File::E_None || errNext == File::E_NOENT,
1253 : OUString("[Java framework] sunjavaplugin: ")
1254 : + "Error while iterating over contens of "
1255 : + usDir2 + ". Osl file error: "
1256 16 : + OUString::number(openErr));
1257 : }
1258 : else
1259 : {
1260 : //usr/java
1261 : //When we look directly into a dir like /usr, /usr/lib, etc. then we only
1262 : //look for certain java directories, such as jre, jdk, etc. Whe do not want
1263 : //to examine the whole directory because of performance reasons.
1264 40 : DirectoryItem item2;
1265 40 : if(DirectoryItem::get(usDir2, item2) == File::E_None)
1266 : {
1267 400 : for( int k= 0; k < cJavaNames; k++)
1268 : {
1269 : // /usr/java/j2re1.4.0
1270 360 : OUString usDir3(usDir2 + arNames[k]);
1271 :
1272 720 : DirectoryItem item3;
1273 360 : if(DirectoryItem::get(usDir3, item) == File::E_None)
1274 : {
1275 : //remove trailing '/'
1276 56 : sal_Int32 islash = usDir3.lastIndexOf('/');
1277 112 : if (islash == usDir3.getLength() - 1
1278 96 : && (islash
1279 40 : > RTL_CONSTASCII_LENGTH("file://")))
1280 32 : usDir3 = usDir3.copy(0, islash);
1281 56 : getJREInfoByPath(usDir3,vecInfos);
1282 : }
1283 360 : }
1284 40 : }
1285 : }
1286 56 : }
1287 : }
1288 64 : }
1289 8 : }
1290 : #endif // ifdef SOLARIS
1291 : #endif // ifdef UNX
1292 : }
1293 :
1294 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|