1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
24 #include <rtl/process.h>
25 #include <rtl/bootstrap.hxx>
26 #include <rtl/random.h>
27 #include <rtl/string.hxx>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/uri.hxx>
30 #include <osl/diagnose.h>
31 #include <osl/file.hxx>
32 #include <osl/security.hxx>
33 #include <osl/thread.hxx>
35 #include <cppuhelper/bootstrap.hxx>
36 #include <cppuhelper/findsofficepath.h>
38 #include <com/sun/star/uno/XComponentContext.hpp>
40 #include <com/sun/star/bridge/UnoUrlResolver.hpp>
41 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
43 #include "macro_expander.hxx"
45 #define ARLEN(x) sizeof (x) / sizeof *(x)
47 using namespace ::osl
;
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::uno
;
57 BootstrapException::BootstrapException()
61 BootstrapException::BootstrapException( const ::rtl::OUString
& rMessage
)
62 :m_aMessage( rMessage
)
66 BootstrapException::BootstrapException( const BootstrapException
& e
)
68 m_aMessage
= e
.m_aMessage
;
71 BootstrapException::~BootstrapException()
75 BootstrapException
& BootstrapException::operator=( const BootstrapException
& e
)
77 m_aMessage
= e
.m_aMessage
;
81 const ::rtl::OUString
& BootstrapException::getMessage() const
86 Reference
< XComponentContext
> SAL_CALL
bootstrap()
88 Reference
< XComponentContext
> xRemoteContext
;
92 char const * p1
= cppuhelper_detail_findSofficePath();
94 throw BootstrapException(
95 "no soffice installation found!");
98 if (!rtl_convertStringToUString(
99 &p2
.pData
, p1
, std::strlen(p1
), osl_getThreadTextEncoding(),
100 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
|
101 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
|
102 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR
)))
104 throw BootstrapException(
105 "bad characters in soffice installation path!");
108 if (osl::FileBase::getFileURLFromSystemPath(p2
, path
) !=
109 osl::FileBase::E_None
)
111 throw BootstrapException(
112 "cannot convert soffice installation path to URL!");
114 if (!path
.isEmpty() && !path
.endsWith("/")) {
119 if (!Bootstrap::get("URE_BOOTSTRAP", uri
)) {
127 SAL_CONFIGFILE("fundamental")));
130 // create default local component context
131 Reference
< XComponentContext
> xLocalContext(
132 defaultBootstrap_InitialComponentContext() );
133 if ( !xLocalContext
.is() )
134 throw BootstrapException( "no local component context!" );
136 // create a random pipe name
137 rtlRandomPool hPool
= rtl_random_createPool();
139 throw BootstrapException( "cannot create random pool!" );
140 sal_uInt8 bytes
[ 16 ];
141 if ( rtl_random_getBytes( hPool
, bytes
, ARLEN( bytes
) )
142 != rtl_Random_E_None
)
143 throw BootstrapException( "random pool error!" );
144 rtl_random_destroyPool( hPool
);
145 ::rtl::OUStringBuffer
buf("uno");
146 for ( sal_uInt32 i
= 0; i
< ARLEN( bytes
); ++i
)
147 buf
.append( static_cast< sal_Int32
>( bytes
[ i
] ) );
148 OUString
sPipeName( buf
.makeStringAndClear() );
152 OUString("--nologo"),
153 OUString("--nodefault"),
154 OUString("--norestore"),
155 OUString("--nolockcheck"),
156 OUString("--accept=pipe,name=" + sPipeName
+ ";urp;")
158 rtl_uString
* ar_args
[] = {
167 // start office process
168 oslProcess hProcess
= 0;
169 oslProcessError rc
= osl_executeProcess(
170 OUString(path
+ "soffice").pData
, ar_args
, ARLEN( ar_args
),
171 osl_Process_DETACHED
,
173 0, // => current working dir
174 0, 0, // => no env vars
178 case osl_Process_E_None
:
179 osl_freeProcessHandle( hProcess
);
181 case osl_Process_E_NotFound
:
182 throw BootstrapException( "image not found!" );
183 case osl_Process_E_TimedOut
:
184 throw BootstrapException( "timeout occurred!" );
185 case osl_Process_E_NoPermission
:
186 throw BootstrapException( "permission denied!" );
187 case osl_Process_E_Unknown
:
188 throw BootstrapException( "unknown error!" );
189 case osl_Process_E_InvalidError
:
191 throw BootstrapException( "unmapped error!" );
194 // create a URL resolver
195 Reference
< bridge::XUnoUrlResolver
> xUrlResolver(
196 bridge::UnoUrlResolver::create( xLocalContext
) );
199 OUString
sConnectString( "uno:pipe,name=" + sPipeName
+ ";urp;StarOffice.ComponentContext" );
201 // wait until office is started
206 // try to connect to office
208 xUrlResolver
->resolve( sConnectString
), UNO_QUERY_THROW
);
211 catch ( connection::NoConnectException
& )
213 // wait 500 ms, then try to connect again
214 TimeValue tv
= { 0 /* secs */, 500000000 /* nanosecs */ };
215 ::osl::Thread::wait( tv
);
219 catch ( Exception
& e
)
221 throw BootstrapException(
222 "unexpected UNO exception caught: " + e
.Message
);
225 return xRemoteContext
;
228 OUString
bootstrap_expandUri(OUString
const & uri
) {
230 return uri
.startsWith("vnd.sun.star.expand:", &rest
)
231 ? cppuhelper::detail::expandMacros(
233 rest
, rtl_UriDecodeWithCharset
, RTL_TEXTENCODING_UTF8
))
239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */