Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "dp_misc.h"
30 : : #include "dp_version.hxx"
31 : : #include "dp_interact.h"
32 : : #include "rtl/uri.hxx"
33 : : #include "rtl/digest.h"
34 : : #include "rtl/random.h"
35 : : #include "rtl/bootstrap.hxx"
36 : : #include "unotools/bootstrap.hxx"
37 : : #include "osl/file.hxx"
38 : : #include "osl/pipe.hxx"
39 : : #include "osl/security.hxx"
40 : : #include "osl/thread.hxx"
41 : : #include "osl/mutex.hxx"
42 : : #include "com/sun/star/ucb/CommandAbortedException.hpp"
43 : : #include "com/sun/star/task/XInteractionHandler.hpp"
44 : : #include "com/sun/star/bridge/UnoUrlResolver.hpp"
45 : : #include "com/sun/star/bridge/XUnoUrlResolver.hpp"
46 : : #include "com/sun/star/deployment/ExtensionManager.hpp"
47 : : #include "com/sun/star/task/XRestartManager.hpp"
48 : : #include "boost/scoped_array.hpp"
49 : : #include "boost/shared_ptr.hpp"
50 : : #include <comphelper/processfactory.hxx>
51 : : #include <salhelper/linkhelper.hxx>
52 : :
53 : : #ifdef WNT
54 : : #define UNICODE
55 : : #define _UNICODE
56 : : #define WIN32_LEAN_AND_MEAN
57 : : #include <windows.h>
58 : : #endif
59 : :
60 : : using namespace ::com::sun::star;
61 : : using namespace ::com::sun::star::uno;
62 : : using ::rtl::OUString;
63 : : using ::rtl::OString;
64 : :
65 : :
66 : : #define SOFFICE1 "soffice.exe"
67 : : #define SOFFICE2 "soffice.bin"
68 : : #define SBASE "sbase.exe"
69 : : #define SCALC "scalc.exe"
70 : : #define SDRAW "sdraw.exe"
71 : : #define SIMPRESS "simpress.exe"
72 : : #define SWRITER "swriter.exe"
73 : :
74 : : namespace dp_misc {
75 : : namespace {
76 : :
77 : : struct UnoRc : public rtl::StaticWithInit<
78 : : boost::shared_ptr<rtl::Bootstrap>, UnoRc> {
79 : 124 : const boost::shared_ptr<rtl::Bootstrap> operator () () {
80 : : OUString unorc( RTL_CONSTASCII_USTRINGPARAM(
81 [ + - ]: 124 : "$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("uno")) );
82 : 124 : ::rtl::Bootstrap::expandMacros( unorc );
83 : : ::boost::shared_ptr< ::rtl::Bootstrap > ret(
84 [ + - ][ + - ]: 124 : new ::rtl::Bootstrap( unorc ) );
85 : : OSL_ASSERT( ret->getHandle() != 0 );
86 : 124 : return ret;
87 : : }
88 : : };
89 : :
90 : : struct OfficePipeId : public rtl::StaticWithInit<OUString, OfficePipeId> {
91 : : const OUString operator () ();
92 : : };
93 : :
94 : 0 : const OUString OfficePipeId::operator () ()
95 : : {
96 : 0 : OUString userPath;
97 : : ::utl::Bootstrap::PathStatus aLocateResult =
98 [ # # ]: 0 : ::utl::Bootstrap::locateUserInstallation( userPath );
99 [ # # ]: 0 : if (!(aLocateResult == ::utl::Bootstrap::PATH_EXISTS ||
100 [ # # ]: 0 : aLocateResult == ::utl::Bootstrap::PATH_VALID))
101 : : {
102 [ # # ][ # # ]: 0 : throw Exception(OUSTR("Extension Manager: Could not obtain path for UserInstallation."), 0);
[ # # ]
103 : : }
104 : :
105 : 0 : rtlDigest digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
106 [ # # ]: 0 : if (!digest) {
107 : : throw RuntimeException(
108 [ # # ][ # # ]: 0 : OUSTR("cannot get digest rtl_Digest_AlgorithmMD5!"), 0 );
[ # # ]
109 : : }
110 : :
111 : : sal_uInt8 const * data =
112 : 0 : reinterpret_cast<sal_uInt8 const *>(userPath.getStr());
113 : 0 : sal_Size size = (userPath.getLength() * sizeof (sal_Unicode));
114 : 0 : sal_uInt32 md5_key_len = rtl_digest_queryLength( digest );
115 [ # # ]: 0 : ::boost::scoped_array<sal_uInt8> md5_buf( new sal_uInt8 [ md5_key_len ] );
116 : :
117 : 0 : rtl_digest_init( digest, data, static_cast<sal_uInt32>(size) );
118 : 0 : rtl_digest_update( digest, data, static_cast<sal_uInt32>(size) );
119 : 0 : rtl_digest_get( digest, md5_buf.get(), md5_key_len );
120 : 0 : rtl_digest_destroy( digest );
121 : :
122 : : // create hex-value string from the MD5 value to keep
123 : : // the string size minimal
124 : 0 : ::rtl::OUStringBuffer buf;
125 [ # # ]: 0 : buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SingleOfficeIPC_") );
126 [ # # ]: 0 : for ( sal_uInt32 i = 0; i < md5_key_len; ++i ) {
127 [ # # ]: 0 : buf.append( static_cast<sal_Int32>(md5_buf[ i ]), 0x10 );
128 : : }
129 [ # # ][ # # ]: 0 : return buf.makeStringAndClear();
130 : : }
131 : :
132 : 0 : bool existsOfficePipe()
133 : : {
134 [ # # ]: 0 : OUString const & pipeId = OfficePipeId::get();
135 [ # # ]: 0 : if (pipeId.isEmpty())
136 : 0 : return false;
137 [ # # ]: 0 : ::osl::Security sec;
138 [ # # ]: 0 : ::osl::Pipe pipe( pipeId, osl_Pipe_OPEN, sec );
139 [ # # ][ # # ]: 0 : return pipe.is();
140 : : }
141 : :
142 : : //get modification time
143 : 384 : static bool getModifyTimeTargetFile(const OUString &rFileURL, TimeValue &rTime)
144 : : {
145 : 384 : salhelper::LinkResolver aResolver(osl_FileStatus_Mask_ModifyTime);
146 : :
147 [ - + ][ + - ]: 384 : if (aResolver.fetchFileStatus(rFileURL) != osl::FileBase::E_None)
148 : 0 : return false;
149 : :
150 [ + - ]: 384 : rTime = aResolver.m_aStatus.getModifyTime();
151 : :
152 : 384 : return true;
153 : : }
154 : :
155 : : //Returns true if the Folder was more recently modified then
156 : : //the lastsynchronized file. That is the repository needs to
157 : : //be synchronized.
158 : 254 : bool compareExtensionFolderWithLastSynchronizedFile(
159 : : OUString const & folderURL, OUString const & fileURL)
160 : : {
161 : 254 : bool bNeedsSync = false;
162 : 254 : ::osl::DirectoryItem itemExtFolder;
163 : : ::osl::File::RC err1 =
164 [ + - ]: 254 : ::osl::DirectoryItem::get(folderURL, itemExtFolder);
165 : : //If it does not exist, then there is nothing to be done
166 [ - + ]: 254 : if (err1 == ::osl::File::E_NOENT)
167 : : {
168 : 0 : return false;
169 : : }
170 [ - + ]: 254 : else if (err1 != ::osl::File::E_None)
171 : : {
172 : : OSL_FAIL("Cannot access extension folder");
173 : 0 : return true; //sync just in case
174 : : }
175 : :
176 : : //If last synchronized does not exist, then OOo is started for the first time
177 : 254 : ::osl::DirectoryItem itemFile;
178 [ + - ]: 254 : ::osl::File::RC err2 = ::osl::DirectoryItem::get(fileURL, itemFile);
179 [ + + ]: 254 : if (err2 == ::osl::File::E_NOENT)
180 : : {
181 : 62 : return true;
182 : :
183 : : }
184 [ - + ]: 192 : else if (err2 != ::osl::File::E_None)
185 : : {
186 : : OSL_FAIL("Cannot access file lastsynchronized");
187 : 0 : return true; //sync just in case
188 : : }
189 : :
190 : : //compare the modification time of the extension folder and the last
191 : : //modified file
192 : : TimeValue timeFolder;
193 [ + - ][ + - ]: 192 : if (getModifyTimeTargetFile(folderURL, timeFolder))
194 : : {
195 : : TimeValue timeFile;
196 [ + - ][ + - ]: 192 : if (getModifyTimeTargetFile(fileURL, timeFile))
197 : : {
198 [ - + ]: 192 : if (timeFile.Seconds < timeFolder.Seconds)
199 : 0 : bNeedsSync = true;
200 : : }
201 : : else
202 : : {
203 : : OSL_ASSERT(0);
204 : 192 : bNeedsSync = true;
205 : : }
206 : : }
207 : : else
208 : : {
209 : : OSL_ASSERT(0);
210 : 0 : bNeedsSync = true;
211 : : }
212 : :
213 [ + - ][ + - ]: 254 : return bNeedsSync;
214 : : }
215 : :
216 : 254 : bool needToSyncRepostitory(OUString const & name)
217 : : {
218 : 254 : OUString folder;
219 : 254 : OUString file;
220 [ + + ]: 254 : if ( name == "bundled" )
221 : : {
222 : : folder = OUString(
223 [ + - ]: 96 : RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS"));
224 : : file = OUString (
225 : : RTL_CONSTASCII_USTRINGPARAM(
226 [ + - ]: 96 : "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
227 : : }
228 [ + - ]: 158 : else if ( name == "shared" )
229 : : {
230 : : folder = OUString(
231 : : RTL_CONSTASCII_USTRINGPARAM(
232 [ + - ]: 158 : "$UNO_SHARED_PACKAGES_CACHE/uno_packages"));
233 : : file = OUString (
234 : : RTL_CONSTASCII_USTRINGPARAM(
235 [ + - ]: 158 : "$SHARED_EXTENSIONS_USER/lastsynchronized"));
236 : : }
237 : : else
238 : : {
239 : : OSL_ASSERT(0);
240 : 0 : return true;
241 : : }
242 : 254 : ::rtl::Bootstrap::expandMacros(folder);
243 : 254 : ::rtl::Bootstrap::expandMacros(file);
244 : : return compareExtensionFolderWithLastSynchronizedFile(
245 [ + - ]: 254 : folder, file);
246 : : }
247 : :
248 : :
249 : : } // anon namespace
250 : :
251 : : //==============================================================================
252 : :
253 : : namespace {
254 : 18400 : inline OUString encodeForRcFile( OUString const & str )
255 : : {
256 : : // escape $\{} (=> rtl bootstrap files)
257 : 18400 : ::rtl::OUStringBuffer buf;
258 : 18400 : sal_Int32 pos = 0;
259 : 18400 : const sal_Int32 len = str.getLength();
260 [ + + ]: 521398 : for ( ; pos < len; ++pos ) {
261 : 502998 : sal_Unicode c = str[ pos ];
262 [ - + ]: 502998 : switch (c) {
263 : : case '$':
264 : : case '\\':
265 : : case '{':
266 : : case '}':
267 [ # # ]: 0 : buf.append( static_cast<sal_Unicode>('\\') );
268 : 0 : break;
269 : : }
270 [ + - ]: 502998 : buf.append( c );
271 : : }
272 [ + - ]: 18400 : return buf.makeStringAndClear();
273 : : }
274 : : }
275 : :
276 : : //==============================================================================
277 : 23543 : OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
278 : : {
279 : 23543 : ::rtl::OUStringBuffer buf;
280 [ + + ][ + + ]: 23543 : if (baseURL.getLength() > 1 && baseURL[ baseURL.getLength() - 1 ] == '/')
[ + - ]
281 [ + - ]: 248 : buf.append( baseURL.copy( 0, baseURL.getLength() - 1 ) );
282 : : else
283 [ + - ]: 23295 : buf.append( baseURL );
284 : 23543 : OUString relPath(relPath_);
285 [ - + ][ - + ]: 23543 : if (!relPath.isEmpty() && relPath[ 0 ] == '/')
[ + + ]
286 : 0 : relPath = relPath.copy( 1 );
287 [ + + ]: 23543 : if (!relPath.isEmpty())
288 : : {
289 [ + - ]: 21171 : buf.append( static_cast<sal_Unicode>('/') );
290 [ + + ]: 21171 : if (baseURL.matchAsciiL(
291 : 21171 : RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
292 : : // encode for macro expansion: relPath is supposed to have no
293 : : // macros, so encode $, {} \ (bootstrap mimic)
294 [ + - ]: 18400 : relPath = encodeForRcFile(relPath);
295 : :
296 : : // encode once more for vnd.sun.star.expand schema:
297 : : // vnd.sun.star.expand:$UNO_...
298 : : // will expand to file-url
299 : : relPath = ::rtl::Uri::encode( relPath, rtl_UriCharClassUric,
300 : : rtl_UriEncodeIgnoreEscapes,
301 : 18400 : RTL_TEXTENCODING_UTF8 );
302 : : }
303 [ + - ]: 21171 : buf.append( relPath );
304 : : }
305 [ + - ]: 23543 : return buf.makeStringAndClear();
306 : : }
307 : :
308 : 502 : OUString makeURLAppendSysPathSegment( OUString const & baseURL, OUString const & relPath_ )
309 : : {
310 : 502 : OUString segment = relPath_;
311 : : OSL_ASSERT(segment.indexOf(static_cast<sal_Unicode>('/')) == -1);
312 : :
313 : : ::rtl::Uri::encode(
314 : : segment, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
315 : 502 : RTL_TEXTENCODING_UTF8);
316 [ + - ]: 502 : return makeURL(baseURL, segment);
317 : : }
318 : :
319 : :
320 : :
321 : : //==============================================================================
322 : 62 : OUString expandUnoRcTerm( OUString const & term_ )
323 : : {
324 : 62 : OUString term(term_);
325 [ + - ]: 62 : UnoRc::get()->expandMacrosFrom( term );
326 : 62 : return term;
327 : : }
328 : :
329 : 6264 : OUString makeRcTerm( OUString const & url )
330 : : {
331 : : OSL_ASSERT( url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM(
332 : : "vnd.sun.star.expand:") ) );
333 [ + - ]: 6264 : if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
334 : : // cut protocol:
335 : 6264 : OUString rcterm( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
336 : : // decode uric class chars:
337 : : rcterm = ::rtl::Uri::decode(
338 : 6264 : rcterm, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
339 : 6264 : return rcterm;
340 : : }
341 : : else
342 : 6264 : return url;
343 : : }
344 : :
345 : : //==============================================================================
346 : 5992 : OUString expandUnoRcUrl( OUString const & url )
347 : : {
348 [ + + ]: 5992 : if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
349 : : // cut protocol:
350 : 5110 : OUString rcurl( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
351 : : // decode uric class chars:
352 : : rcurl = ::rtl::Uri::decode(
353 : 5110 : rcurl, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
354 : : // expand macro string:
355 [ + - ]: 5110 : UnoRc::get()->expandMacrosFrom( rcurl );
356 : 5110 : return rcurl;
357 : : }
358 : : else {
359 : 5992 : return url;
360 : : }
361 : : }
362 : :
363 : : //==============================================================================
364 : 0 : bool office_is_running()
365 : : {
366 : : //We need to check if we run within the office process. Then we must not use the pipe, because
367 : : //this could cause a deadlock. This is actually a workaround for i82778
368 : 0 : OUString sFile;
369 [ # # ]: 0 : oslProcessError err = osl_getExecutableFile(& sFile.pData);
370 : 0 : bool ret = false;
371 [ # # ]: 0 : if (osl_Process_E_None == err)
372 : : {
373 : 0 : sFile = sFile.copy(sFile.lastIndexOf('/') + 1);
374 [ # # ]: 0 : if (
375 : : #if defined UNIX
376 : : sFile == SOFFICE2
377 : : #elif defined WNT
378 : : //osl_getExecutableFile should deliver "soffice.bin" on windows
379 : : //even if swriter.exe, scalc.exe etc. was started. This is a bug
380 : : //in osl_getExecutableFile
381 : : sFile == SOFFICE1 || sFile == SOFFICE2 || sFile == SBASE || sFile == SCALC
382 : : || sFile == SDRAW || sFile == SIMPRESS || sFile == SWRITER
383 : : #else
384 : : #error "Unsupported platform"
385 : : #endif
386 : :
387 : : )
388 : 0 : ret = true;
389 : : else
390 [ # # ]: 0 : ret = existsOfficePipe();
391 : : }
392 : : else
393 : : {
394 : : OSL_FAIL("NOT osl_Process_E_None ");
395 : : //if osl_getExecutable file than we take the risk of creating a pipe
396 [ # # ]: 0 : ret = existsOfficePipe();
397 : : }
398 : 0 : return ret;
399 : : }
400 : :
401 : : //==============================================================================
402 : 2 : oslProcess raiseProcess(
403 : : OUString const & appURL, Sequence<OUString> const & args )
404 : : {
405 [ + - ]: 2 : ::osl::Security sec;
406 : 2 : oslProcess hProcess = 0;
407 : : oslProcessError rc = osl_executeProcess(
408 : : appURL.pData,
409 : : reinterpret_cast<rtl_uString **>(
410 : 2 : const_cast<OUString *>(args.getConstArray()) ),
411 : 2 : args.getLength(),
412 : : osl_Process_DETACHED,
413 : : sec.getHandle(),
414 : : 0, // => current working dir
415 : : 0, 0, // => no env vars
416 [ + - ]: 4 : &hProcess );
417 : :
418 [ + - - - : 2 : switch (rc) {
- - ]
419 : : case osl_Process_E_None:
420 : 2 : break;
421 : : case osl_Process_E_NotFound:
422 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("image not found!"), 0 );
[ # # ]
423 : : case osl_Process_E_TimedOut:
424 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("timout occurred!"), 0 );
[ # # ]
425 : : case osl_Process_E_NoPermission:
426 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("permission denied!"), 0 );
[ # # ]
427 : : case osl_Process_E_Unknown:
428 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("unknown error!"), 0 );
[ # # ]
429 : : case osl_Process_E_InvalidError:
430 : : default:
431 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("unmapped error!"), 0 );
[ # # ]
432 : : }
433 : :
434 [ + - ]: 2 : return hProcess;
435 : : }
436 : :
437 : : //==============================================================================
438 : 2 : OUString generateRandomPipeId()
439 : : {
440 : : // compute some good pipe id:
441 [ + - ][ + - ]: 2 : static rtlRandomPool s_hPool = rtl_random_createPool();
442 [ - + ]: 2 : if (s_hPool == 0)
443 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("cannot create random pool!?"), 0 );
[ # # ]
444 : : sal_uInt8 bytes[ 32 ];
445 [ - + ]: 2 : if (rtl_random_getBytes(
446 : 2 : s_hPool, bytes, ARLEN(bytes) ) != rtl_Random_E_None) {
447 [ # # ][ # # ]: 0 : throw RuntimeException( OUSTR("random pool error!?"), 0 );
[ # # ]
448 : : }
449 : 2 : ::rtl::OUStringBuffer buf;
450 [ + + ]: 66 : for ( sal_uInt32 i = 0; i < ARLEN(bytes); ++i ) {
451 [ + - ]: 64 : buf.append( static_cast<sal_Int32>(bytes[ i ]), 0x10 );
452 : : }
453 [ + - ]: 2 : return buf.makeStringAndClear();
454 : : }
455 : :
456 : : //==============================================================================
457 : 2 : Reference<XInterface> resolveUnoURL(
458 : : OUString const & connectString,
459 : : Reference<XComponentContext> const & xLocalContext,
460 : : AbortChannel * abortChannel )
461 : : {
462 : : Reference<bridge::XUnoUrlResolver> xUnoUrlResolver(
463 [ + - ]: 2 : bridge::UnoUrlResolver::create( xLocalContext ) );
464 : :
465 : 7 : for (;;)
466 : : {
467 [ + - ][ - + ]: 9 : if (abortChannel != 0 && abortChannel->isAborted()) {
[ - + ]
468 : : throw ucb::CommandAbortedException(
469 [ # # ][ # # ]: 0 : OUSTR("abort!"), Reference<XInterface>() );
470 : : }
471 : : try {
472 [ + - ][ + + ]: 11 : return xUnoUrlResolver->resolve( connectString );
473 : : }
474 [ - + ][ + - ]: 14 : catch (const connection::NoConnectException &) {
475 : 7 : TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
476 [ - + ]: 7 : ::osl::Thread::wait( tv );
477 : : }
478 : 2 : }
479 : : }
480 : :
481 : : #ifdef WNT
482 : : void writeConsoleWithStream(::rtl::OUString const & sText, HANDLE stream)
483 : : {
484 : : DWORD nWrittenChars = 0;
485 : : WriteFile(stream, sText.getStr(),
486 : : sText.getLength() * 2, &nWrittenChars, NULL);
487 : : }
488 : : #else
489 : 0 : void writeConsoleWithStream(::rtl::OUString const & sText, FILE * stream)
490 : : {
491 [ # # ][ # # ]: 0 : OString s = OUStringToOString(sText, osl_getThreadTextEncoding());
492 [ # # ]: 0 : fprintf(stream, "%s", s.getStr());
493 [ # # ]: 0 : fflush(stream);
494 : 0 : }
495 : : #endif
496 : :
497 : 0 : void writeConsole(::rtl::OUString const & sText)
498 : : {
499 : : #ifdef WNT
500 : : writeConsoleWithStream(sText, GetStdHandle(STD_OUTPUT_HANDLE));
501 : : #else
502 : 0 : writeConsoleWithStream(sText, stdout);
503 : : #endif
504 : 0 : }
505 : :
506 : 0 : void writeConsoleError(::rtl::OUString const & sText)
507 : : {
508 : : #ifdef WNT
509 : : writeConsoleWithStream(sText, GetStdHandle(STD_ERROR_HANDLE));
510 : : #else
511 : 0 : writeConsoleWithStream(sText, stderr);
512 : : #endif
513 : 0 : }
514 : :
515 : 0 : OUString readConsole()
516 : : {
517 : : #ifdef WNT
518 : : sal_Unicode aBuffer[1024];
519 : : DWORD dwRead = 0;
520 : : //unopkg.com feeds unopkg.exe with wchar_t|s
521 : : if (ReadFile( GetStdHandle(STD_INPUT_HANDLE), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
522 : : {
523 : : OSL_ASSERT((dwRead % 2) == 0);
524 : : OUString value( aBuffer, dwRead / 2);
525 : : return value.trim();
526 : : }
527 : : #else
528 : : char buf[1024];
529 [ # # ]: 0 : rtl_zeroMemory(buf, 1024);
530 : : // read one char less so that the last char in buf is always zero
531 [ # # ][ # # ]: 0 : if (fgets(buf, 1024, stdin) != NULL)
532 : : {
533 [ # # ][ # # ]: 0 : OUString value = ::rtl::OStringToOUString(::rtl::OString(buf), osl_getThreadTextEncoding());
534 : 0 : return value.trim();
535 : : }
536 : : #endif
537 : 0 : return OUString();
538 : : }
539 : :
540 : 0 : void TRACE(::rtl::OUString const & sText)
541 : : {
542 : : (void) sText;
543 : : #if OSL_DEBUG_LEVEL > 1
544 : : writeConsole(sText);
545 : : #endif
546 : 0 : }
547 : :
548 : 158 : void syncRepositories(
549 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv)
550 : : {
551 : 158 : OUString sDisable;
552 [ + - ]: 158 : ::rtl::Bootstrap::get( OUSTR( "DISABLE_EXTENSION_SYNCHRONIZATION" ), sDisable, OUString() );
553 [ - + ]: 158 : if (!sDisable.isEmpty())
554 : 158 : return;
555 : :
556 : 158 : Reference<deployment::XExtensionManager> xExtensionManager;
557 : : //synchronize shared before bundled otherewise there are
558 : : //more revoke and registration calls.
559 : 158 : sal_Bool bModified = false;
560 [ + - ][ + + ]: 412 : if (needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared")))
[ - + ][ + - ]
[ + + # # ]
[ + - ]
561 [ + - ][ + - ]: 254 : || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled"))))
[ + + ][ # # ]
562 : : {
563 : : xExtensionManager =
564 : : deployment::ExtensionManager::get(
565 [ + - ][ + - ]: 62 : comphelper_getProcessComponentContext());
[ + - ][ + - ]
566 : :
567 [ + - ]: 62 : if (xExtensionManager.is())
568 : : {
569 [ + - ]: 62 : bModified = xExtensionManager->synchronize(
570 [ + - ]: 62 : Reference<task::XAbortChannel>(), xCmdEnv);
571 : : }
572 : : }
573 : :
574 [ + + ]: 158 : if (bModified)
575 : : {
576 : : Reference<task::XRestartManager> restarter(
577 [ + - ]: 62 : comphelper_getProcessComponentContext()->getValueByName(
578 [ + - ][ + - ]: 62 : OUSTR( "/singletons/com.sun.star.task.OfficeRestartManager") ), UNO_QUERY );
[ + - ]
579 [ + - ]: 62 : if (restarter.is())
580 : : {
581 : : OSL_TRACE( "Request restart for modified extensions manager" );
582 [ + - ][ + - ]: 124 : restarter->requestRestart(xCmdEnv.is() == sal_True ? xCmdEnv->getInteractionHandler() :
583 [ + - ][ + - ]: 124 : Reference<task::XInteractionHandler>());
[ + - ]
584 : 62 : }
585 [ + - ]: 158 : }
586 : : }
587 : :
588 : :
589 : :
590 : : }
591 : :
592 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|