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>
22 #include "acceptor.hxx"
23 #include <com/sun/star/bridge/BridgeFactory.hpp>
24 #include <com/sun/star/connection/Acceptor.hpp>
25 #include <com/sun/star/uno/XNamingService.hpp>
26 #include <officecfg/Office/Security.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <sal/log.hxx>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <o3tl/string_view.hxx>
32 using namespace css::bridge
;
33 using namespace css::connection
;
34 using namespace css::lang
;
35 using namespace css::uno
;
42 static void offacc_workerfunc (void * acc
)
44 osl_setThreadName("URP Acceptor");
46 static_cast<Acceptor
*>(acc
)->run();
51 Acceptor::Acceptor( const Reference
< XComponentContext
>& rxContext
)
53 , m_rContext(rxContext
)
57 m_rAcceptor
= css::connection::Acceptor::create(m_rContext
);
58 m_rBridgeFactory
= BridgeFactory::create(m_rContext
);
64 m_rAcceptor
->stopAccepting();
67 std::unique_lock
g(m_aMutex
);
70 //prevent locking if the thread is still waiting
73 osl_joinWithThread(t
);
76 // Make the final state of m_bridges visible to this thread (since
77 // m_thread is joined, the code that follows is the only one left
78 // accessing m_bridges):
79 std::unique_lock
g(m_aMutex
);
82 css::uno::Reference
< css::bridge::XBridge
> b(m_bridges
.remove());
86 css::uno::Reference
< css::lang::XComponent
>(
87 b
, css::uno::UNO_QUERY_THROW
)->dispose();
93 SAL_INFO( "desktop.offacc", "Acceptor::run" );
98 // wait until we get enabled
99 SAL_INFO( "desktop.offacc",
100 "Acceptor::run waiting for office to come up");
102 if (m_bDying
) //see destructor
104 SAL_INFO( "desktop.offacc",
105 "Acceptor::run now enabled and continuing");
107 std::unique_lock
g(m_aMutex
);
110 Reference
< XConnection
> rConnection
= m_rAcceptor
->accept( m_aConnectString
);
111 // if we return without a valid connection we must assume that the acceptor
112 // is destructed so we break out of the run method terminating the thread
113 if (! rConnection
.is()) break;
114 OUString aDescription
= rConnection
->getDescription();
115 SAL_INFO( "desktop.offacc", "Acceptor::run connection " << aDescription
);
117 // create instanceprovider for this connection
118 Reference
< XInstanceProvider
> rInstanceProvider(new AccInstanceProvider(m_rContext
));
119 // create the bridge. The remote end will have a reference to this bridge
120 // thus preventing the bridge from being disposed. When the remote end releases
121 // the bridge, it will be destructed.
122 m_bridges
.add(m_rBridgeFactory
->createBridge(
123 u
""_ustr
, m_aProtocol
, rConnection
, rInstanceProvider
));
124 } catch (const Exception
&) {
125 TOOLS_WARN_EXCEPTION("desktop.offacc", "");
126 // connection failed...
127 // something went wrong during connection setup.
128 // just wait for a new connection to accept
134 void Acceptor::initialize( const Sequence
<Any
>& aArguments
)
136 // prevent multiple initialization
137 std::unique_lock
aGuard( m_aMutex
);
138 SAL_INFO( "desktop.offacc", "Acceptor::initialize()" );
143 int nArgs
= aArguments
.getLength();
145 // not yet initialized and accept-string
146 if (!m_bInit
&& nArgs
> 0 && (aArguments
[0] >>= m_aAcceptString
))
148 SAL_INFO( "desktop.offacc", "Acceptor::initialize string=" << m_aAcceptString
);
150 // get connect string and protocol from accept string
151 // "<connectString>;<protocol>"
152 sal_Int32 nIndex1
= m_aAcceptString
.indexOf( ';' );
154 throw IllegalArgumentException(
155 u
"Invalid accept-string format"_ustr
, m_rContext
, 1);
156 m_aConnectString
= o3tl::trim(m_aAcceptString
.subView( 0 , nIndex1
));
158 sal_Int32 nIndex2
= m_aAcceptString
.indexOf( ';' , nIndex1
);
159 if (nIndex2
< 0) nIndex2
= m_aAcceptString
.getLength();
160 m_aProtocol
= m_aAcceptString
.copy( nIndex1
, nIndex2
- nIndex1
);
162 // start accepting in new thread...
163 m_thread
= osl_createThread(offacc_workerfunc
, this);
168 // do we want to enable accepting?
169 bool bEnable
= false;
170 if (((nArgs
== 1 && (aArguments
[0] >>= bEnable
)) ||
171 (nArgs
== 2 && (aArguments
[1] >>= bEnable
))) &&
180 throw IllegalArgumentException( u
"invalid initialization"_ustr
, m_rContext
, 1);
185 OUString
Acceptor::getImplementationName()
187 return u
"com.sun.star.office.comp.Acceptor"_ustr
;
189 Sequence
<OUString
> Acceptor::getSupportedServiceNames()
191 return { u
"com.sun.star.office.Acceptor"_ustr
};
194 sal_Bool
Acceptor::supportsService(OUString
const & ServiceName
)
196 return cppu::supportsService(this, ServiceName
);
201 AccInstanceProvider::AccInstanceProvider(const Reference
<XComponentContext
>& rxContext
)
202 : m_rContext(rxContext
)
206 AccInstanceProvider::~AccInstanceProvider()
210 Reference
<XInterface
> AccInstanceProvider::getInstance (const OUString
& aName
)
213 Reference
<XInterface
> rInstance
;
215 if ( aName
== "StarOffice.ServiceManager" )
217 rInstance
.set( m_rContext
->getServiceManager() );
219 else if ( aName
== "StarOffice.ComponentContext" )
221 rInstance
= m_rContext
;
223 else if ( aName
== "StarOffice.NamingService" )
225 Reference
< XNamingService
> rNamingService(
226 m_rContext
->getServiceManager()->createInstanceWithContext(u
"com.sun.star.uno.NamingService"_ustr
, m_rContext
),
228 if ( rNamingService
.is() )
230 rNamingService
->registerObject( u
"StarOffice.ServiceManager"_ustr
, m_rContext
->getServiceManager() );
231 rNamingService
->registerObject( u
"StarOffice.ComponentContext"_ustr
, m_rContext
);
232 rInstance
= rNamingService
;
240 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
241 desktop_Acceptor_get_implementation(
242 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
244 if (!officecfg::Office::Security::Net::AllowInsecureUNORemoteProtocol::get())
246 // this is not allowed to throw
247 SAL_WARN("desktop", "UNO Remote Protocol is disabled by configuration");
250 return cppu::acquire(new desktop::Acceptor(context
));
254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */