1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <stdio.h>
25 #include <vector>
26
27 #include "sal/main.h"
28 #include <osl/diagnose.h>
29 #include <osl/mutex.hxx>
30 #include <osl/conditn.hxx>
31 #include <osl/module.h>
32
33 #include <rtl/process.h>
34 #include <rtl/string.h>
35 #include <rtl/strbuf.hxx>
36 #include <rtl/ustrbuf.hxx>
37
38 #include <uno/environment.h>
39 #include <uno/mapping.hxx>
40
41 #include <cppuhelper/factory.hxx>
42 #include <cppuhelper/bootstrap.hxx>
43 #include <cppuhelper/servicefactory.hxx>
44 #include <cppuhelper/shlib.hxx>
45 #include <cppuhelper/implbase1.hxx>
46
47 #include <com/sun/star/lang/XMain.hpp>
48 #include <com/sun/star/lang/XInitialization.hpp>
49 #include <com/sun/star/lang/XComponent.hpp>
50 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
51 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
52 #include <com/sun/star/lang/XEventListener.hpp>
53 #include <com/sun/star/container/XSet.hpp>
54 #include <com/sun/star/loader/XImplementationLoader.hpp>
55 #include <com/sun/star/registry/XSimpleRegistry.hpp>
56 #include <com/sun/star/registry/XRegistryKey.hpp>
57 #include <com/sun/star/connection/XAcceptor.hpp>
58 #include <com/sun/star/connection/XConnection.hpp>
59 #include <com/sun/star/bridge/XBridgeFactory.hpp>
60 #include <com/sun/star/bridge/XBridge.hpp>
61 #include <osl/process.h>
62 #include <osl/thread.h>
63 #include <osl/file.hxx>
64
65 #ifdef SAL_UNX
66 #define SEPARATOR '/'
67 #else
68 #define SEPARATOR '\\'
69 #endif
70
71 using namespace std;
72 using namespace rtl;
73 using namespace osl;
74 using namespace cppu;
75 using namespace com::sun::star::uno;
76 using namespace com::sun::star::lang;
77 using namespace com::sun::star::loader;
78 using namespace com::sun::star::registry;
79 using namespace com::sun::star::connection;
80 using namespace com::sun::star::bridge;
81 using namespace com::sun::star::container;
82
83 namespace unoexe
84 {
85
isFileUrl(const OUString & fileName)86 static sal_Bool isFileUrl(const OUString& fileName)
87 {
88 if (fileName.indexOf(OUString::createFromAscii("file://")) == 0 )
89 return sal_True;
90 return sal_False;
91 }
92
convertToFileUrl(const OUString & fileName)93 static OUString convertToFileUrl(const OUString& fileName)
94 {
95 if ( isFileUrl(fileName) )
96 {
97 return fileName;
98 }
99
100 OUString uUrlFileName;
101 if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
102 {
103 OUString uWorkingDir;
104 if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
105 OSL_ASSERT(false);
106 }
107 if (FileBase::getAbsoluteFileURL(uWorkingDir, fileName, uUrlFileName)
108 != FileBase::E_None)
109 {
110 OSL_ASSERT(false);
111 }
112 } else
113 {
114 if (FileBase::getFileURLFromSystemPath(fileName, uUrlFileName)
115 != FileBase::E_None)
116 {
117 OSL_ASSERT(false);
118 }
119 }
120
121 return uUrlFileName;
122 }
123
124 static sal_Bool s_quiet = false;
125
126 //--------------------------------------------------------------------------------------------------
out(const sal_Char * pText)127 static inline void out( const sal_Char * pText )
128 {
129 if (! s_quiet)
130 fprintf( stderr, pText );
131 }
132 //--------------------------------------------------------------------------------------------------
out(const OUString & rText)133 static inline void out( const OUString & rText )
134 {
135 if (! s_quiet)
136 {
137 OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
138 fprintf( stderr, aText.getStr() );
139 }
140 }
141
142 //--------------------------------------------------------------------------------------------------
143 static const char arUsingText[] =
144 "\nusing:\n\n"
145 "uno [-c ComponentImplementationName -l LocationUrl | -s ServiceName]\n"
146 " [-ro ReadOnlyRegistry1] [-ro ReadOnlyRegistry2] ... [-rw ReadWriteRegistry]\n"
147 " [-u uno:(socket[,host=HostName][,port=nnn]|pipe[,name=PipeName]);<protocol>;Name\n"
148 " [--singleaccept] [--singleinstance]]\n"
149 " [--quiet]\n"
150 " [-- Argument1 Argument2 ...]\n";
151
152 //--------------------------------------------------------------------------------------------------
readOption(OUString * pValue,const sal_Char * pOpt,sal_Int32 * pnIndex,const OUString & aArg)153 static sal_Bool readOption( OUString * pValue, const sal_Char * pOpt,
154 sal_Int32 * pnIndex, const OUString & aArg)
155 throw (RuntimeException)
156 {
157 const OUString dash = OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
158 if(aArg.indexOf(dash) != 0)
159 return sal_False;
160
161 OUString aOpt = OUString::createFromAscii( pOpt );
162
163 if (aArg.getLength() < aOpt.getLength())
164 return sal_False;
165
166 if (aOpt.equalsIgnoreAsciiCase( aArg.copy(1) ))
167 {
168 // take next argument
169 ++(*pnIndex);
170
171 rtl_getAppCommandArg(*pnIndex, &pValue->pData);
172 if (*pnIndex >= (sal_Int32)rtl_getAppCommandArgCount() || pValue->copy(1).equals(dash))
173 {
174 OUStringBuffer buf( 32 );
175 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("incomplete option \"-") );
176 buf.appendAscii( pOpt );
177 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" given!") );
178 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
179 }
180 else
181 {
182 #if OSL_DEBUG_LEVEL > 1
183 out( "\n> identified option -" );
184 out( pOpt );
185 out( " = " );
186 OString tmp = OUStringToOString(aArg, RTL_TEXTENCODING_ASCII_US);
187 out( tmp.getStr() );
188 #endif
189 ++(*pnIndex);
190 return sal_True;
191 }
192 }
193 else if (aArg.indexOf(aOpt) == 1)
194 {
195 *pValue = aArg.copy(1 + aOpt.getLength());
196 #if OSL_DEBUG_LEVEL > 1
197 out( "\n> identified option -" );
198 out( pOpt );
199 out( " = " );
200 OString tmp = OUStringToOString(aArg.copy(aOpt.getLength()), RTL_TEXTENCODING_ASCII_US);
201 out( tmp.getStr() );
202 #endif
203 ++(*pnIndex);
204
205 return sal_True;
206 }
207 return sal_False;
208 }
209 //--------------------------------------------------------------------------------------------------
readOption(sal_Bool * pbOpt,const sal_Char * pOpt,sal_Int32 * pnIndex,const OUString & aArg)210 static sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt,
211 sal_Int32 * pnIndex, const OUString & aArg)
212 {
213 const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--"));
214 OUString aOpt = OUString::createFromAscii(pOpt);
215
216 if(aArg.indexOf(dashdash) == 0 && aOpt.equals(aArg.copy(2)))
217 {
218 ++(*pnIndex);
219 *pbOpt = sal_True;
220 #if OSL_DEBUG_LEVEL > 1
221 out( "\n> identified option --" );
222 out( pOpt );
223 #endif
224 return sal_True;
225 }
226 return sal_False;
227 }
228
229
230 //##################################################################################################
231 //##################################################################################################
232 //##################################################################################################
233
234
235 //--------------------------------------------------------------------------------------------------
236 template< class T >
createInstance(Reference<T> & rxOut,const Reference<XComponentContext> & xContext,const OUString & rServiceName)237 void createInstance(
238 Reference< T > & rxOut,
239 const Reference< XComponentContext > & xContext,
240 const OUString & rServiceName )
241 throw (Exception)
242 {
243 Reference< XMultiComponentFactory > xMgr( xContext->getServiceManager() );
244 Reference< XInterface > x( xMgr->createInstanceWithContext( rServiceName, xContext ) );
245
246 if (! x.is())
247 {
248 static sal_Bool s_bSet = sal_False;
249 if (! s_bSet)
250 {
251 MutexGuard aGuard( Mutex::getGlobalMutex() );
252 if (! s_bSet)
253 {
254 Reference< XSet > xSet( xMgr, UNO_QUERY );
255 if (xSet.is())
256 {
257 Reference< XMultiServiceFactory > xSF( xMgr, UNO_QUERY );
258 // acceptor
259 xSet->insert( makeAny( loadSharedLibComponentFactory(
260 OUString( RTL_CONSTASCII_USTRINGPARAM(
261 "acceptor.uno" SAL_DLLEXTENSION) ),
262 OUString(),
263 OUString( RTL_CONSTASCII_USTRINGPARAM(
264 "com.sun.star.comp.io.Acceptor") ),
265 xSF, Reference< XRegistryKey >() ) ) );
266 // connector
267 xSet->insert( makeAny( loadSharedLibComponentFactory(
268 OUString( RTL_CONSTASCII_USTRINGPARAM(
269 "connector.uno" SAL_DLLEXTENSION) ),
270 OUString(),
271 OUString( RTL_CONSTASCII_USTRINGPARAM(
272 "com.sun.star.comp.io.Connector") ),
273 xSF, Reference< XRegistryKey >() ) ) );
274 // bridge factory
275 xSet->insert( makeAny( loadSharedLibComponentFactory(
276 OUString( RTL_CONSTASCII_USTRINGPARAM(
277 "binaryurp.uno" SAL_DLLEXTENSION) ),
278 OUString(),
279 OUString(
280 RTL_CONSTASCII_USTRINGPARAM(
281 "com.sun.star.comp.bridge.BridgeFactory") ),
282 xSF, Reference< XRegistryKey >() ) ) );
283 }
284 s_bSet = sal_True;
285 }
286 }
287 x = xMgr->createInstanceWithContext( rServiceName, xContext );
288 }
289
290 if (! x.is())
291 {
292 OUStringBuffer buf( 64 );
293 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
294 buf.append( rServiceName );
295 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
296 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
297 }
298
299 rxOut = Reference< T >::query( x );
300 if (! rxOut.is())
301 {
302 OUStringBuffer buf( 64 );
303 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
304 buf.append( rServiceName );
305 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
306 const Type & rType = ::getCppuType( (const Reference< T > *)0 );
307 buf.append( rType.getTypeName() );
308 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
309 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
310 }
311 }
312 //--------------------------------------------------------------------------------------------------
nestRegistries(const Reference<XSimpleRegistry> & xReadWrite,const Reference<XSimpleRegistry> & xReadOnly)313 static Reference< XSimpleRegistry > nestRegistries(
314 const Reference< XSimpleRegistry > & xReadWrite,
315 const Reference< XSimpleRegistry > & xReadOnly )
316 throw (Exception)
317 {
318 Reference< XSimpleRegistry > xReg( createNestedRegistry() );
319 if (! xReg.is())
320 {
321 throw RuntimeException(
322 OUString( RTL_CONSTASCII_USTRINGPARAM("no nested registry service!" ) ),
323 Reference< XInterface >() );
324 }
325
326 Reference< XInitialization > xInit( xReg, UNO_QUERY );
327 if (! xInit.is())
328 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("nested registry does not export interface \"com.sun.star.lang.XInitialization\"!" ) ), Reference< XInterface >() );
329
330 Sequence< Any > aArgs( 2 );
331 aArgs[0] <<= xReadWrite;
332 aArgs[1] <<= xReadOnly;
333 xInit->initialize( aArgs );
334
335 return xReg;
336 }
337 //--------------------------------------------------------------------------------------------------
openRegistry(const OUString & rURL,sal_Bool bReadOnly,sal_Bool bCreate)338 static Reference< XSimpleRegistry > openRegistry(
339 const OUString & rURL,
340 sal_Bool bReadOnly, sal_Bool bCreate )
341 throw (Exception)
342 {
343 Reference< XSimpleRegistry > xNewReg( createSimpleRegistry() );
344 if (! xNewReg.is())
345 {
346 throw RuntimeException(
347 OUString( RTL_CONSTASCII_USTRINGPARAM("no simple registry service!" ) ),
348 Reference< XInterface >() );
349 }
350
351 try
352 {
353 xNewReg->open( convertToFileUrl(rURL), bReadOnly, bCreate );
354 if (xNewReg->isValid())
355 return xNewReg;
356 else
357 xNewReg->close();
358 }
359 catch (Exception &)
360 {
361 }
362
363 out( "\n> warning: cannot open registry \"" );
364 out( rURL );
365 if (bReadOnly)
366 out( "\" for reading, ignoring!" );
367 else
368 out( "\" for reading and writing, ignoring!" );
369 return Reference< XSimpleRegistry >();
370 }
371 //--------------------------------------------------------------------------------------------------
loadComponent(const Reference<XComponentContext> & xContext,const OUString & rImplName,const OUString & rLocation)372 static Reference< XInterface > loadComponent(
373 const Reference< XComponentContext > & xContext,
374 const OUString & rImplName, const OUString & rLocation )
375 throw (Exception)
376 {
377 // determine loader to be used
378 sal_Int32 nDot = rLocation.lastIndexOf( '.' );
379 if (nDot > 0 && nDot < rLocation.getLength())
380 {
381 Reference< XImplementationLoader > xLoader;
382
383 OUString aExt( rLocation.copy( nDot +1 ) );
384
385 if (aExt.compareToAscii( "dll" ) == 0 ||
386 aExt.compareToAscii( "exe" ) == 0 ||
387 aExt.compareToAscii( "dylib" ) == 0 ||
388 aExt.compareToAscii( "so" ) == 0)
389 {
390 createInstance(
391 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ) );
392 }
393 else if (aExt.compareToAscii( "jar" ) == 0 ||
394 aExt.compareToAscii( "class" ) == 0)
395 {
396 createInstance(
397 xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ) );
398 }
399 else
400 {
401 OUStringBuffer buf( 64 );
402 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unknown extension of \"") );
403 buf.append( rLocation );
404 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"! No loader available!") );
405 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
406 }
407
408 Reference< XInterface > xInstance;
409
410 // activate
411 Reference< XInterface > xFactory( xLoader->activate(
412 rImplName, OUString(), rLocation, Reference< XRegistryKey >() ) );
413 if (xFactory.is())
414 {
415 Reference< XSingleComponentFactory > xCFac( xFactory, UNO_QUERY );
416 if (xCFac.is())
417 {
418 xInstance = xCFac->createInstanceWithContext( xContext );
419 }
420 else
421 {
422 Reference< XSingleServiceFactory > xSFac( xFactory, UNO_QUERY );
423 if (xSFac.is())
424 {
425 out( "\n> warning: ignroing context for implementation \"" );
426 out( rImplName );
427 out( "\"!" );
428 xInstance = xSFac->createInstance();
429 }
430 }
431 }
432
433 if (! xInstance.is())
434 {
435 OUStringBuffer buf( 64 );
436 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("activating component \"") );
437 buf.append( rImplName );
438 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from location \"") );
439 buf.append( rLocation );
440 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" failed!") );
441 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
442 }
443
444 return xInstance;
445 }
446 else
447 {
448 OUStringBuffer buf( 64 );
449 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("location \"") );
450 buf.append( rLocation );
451 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" has no extension! Cannot determine loader to be used!") );
452 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
453 }
454 }
455
456
457 //##################################################################################################
458 //##################################################################################################
459 //##################################################################################################
460
461
462 //==================================================================================================
463 class OInstanceProvider
464 : public WeakImplHelper1< XInstanceProvider >
465 {
466 Reference< XComponentContext > _xContext;
467
468 Mutex _aSingleInstanceMutex;
469 Reference< XInterface > _xSingleInstance;
470 sal_Bool _bSingleInstance;
471
472 OUString _aImplName;
473 OUString _aLocation;
474 OUString _aServiceName;
475 Sequence< Any > _aInitParams;
476
477 OUString _aInstanceName;
478
479 inline Reference< XInterface > createInstance() throw (Exception);
480
481 public:
OInstanceProvider(const Reference<XComponentContext> & xContext,const OUString & rImplName,const OUString & rLocation,const OUString & rServiceName,const Sequence<Any> & rInitParams,sal_Bool bSingleInstance,const OUString & rInstanceName)482 OInstanceProvider( const Reference< XComponentContext > & xContext,
483 const OUString & rImplName, const OUString & rLocation,
484 const OUString & rServiceName, const Sequence< Any > & rInitParams,
485 sal_Bool bSingleInstance, const OUString & rInstanceName )
486 : _xContext( xContext )
487 , _bSingleInstance( bSingleInstance )
488 , _aImplName( rImplName )
489 , _aLocation( rLocation )
490 , _aServiceName( rServiceName )
491 , _aInitParams( rInitParams )
492 , _aInstanceName( rInstanceName )
493 {}
494
495 // XInstanceProvider
496 virtual Reference< XInterface > SAL_CALL getInstance( const OUString & rName )
497 throw (NoSuchElementException, RuntimeException);
498 };
499 //__________________________________________________________________________________________________
createInstance()500 inline Reference< XInterface > OInstanceProvider::createInstance()
501 throw (Exception)
502 {
503 Reference< XInterface > xRet;
504 if (_aImplName.getLength()) // manually via loader
505 xRet = loadComponent( _xContext, _aImplName, _aLocation );
506 else // via service manager
507 unoexe::createInstance( xRet, _xContext, _aServiceName );
508
509 // opt XInit
510 Reference< XInitialization > xInit( xRet, UNO_QUERY );
511 if (xInit.is())
512 xInit->initialize( _aInitParams );
513
514 return xRet;
515 }
516 //__________________________________________________________________________________________________
getInstance(const OUString & rName)517 Reference< XInterface > OInstanceProvider::getInstance( const OUString & rName )
518 throw (NoSuchElementException, RuntimeException)
519 {
520 try
521 {
522 if (_aInstanceName == rName)
523 {
524 Reference< XInterface > xRet;
525
526 if (_aImplName.getLength() == 0 && _aServiceName.getLength() == 0)
527 {
528 OSL_ASSERT(
529 rName.equalsAsciiL(
530 RTL_CONSTASCII_STRINGPARAM("uno.ComponentContext") ) );
531 xRet = _xContext;
532 }
533 else if (_bSingleInstance)
534 {
535 if (! _xSingleInstance.is())
536 {
537 MutexGuard aGuard( _aSingleInstanceMutex );
538 if (! _xSingleInstance.is())
539 {
540 _xSingleInstance = createInstance();
541 }
542 }
543 xRet = _xSingleInstance;
544 }
545 else
546 {
547 xRet = createInstance();
548 }
549
550 return xRet;
551 }
552 }
553 catch (Exception & rExc)
554 {
555 out( "\n> error: " );
556 out( rExc.Message );
557 }
558 OUStringBuffer buf( 64 );
559 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("no such element \"") );
560 buf.append( rName );
561 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
562 throw NoSuchElementException( buf.makeStringAndClear(), Reference< XInterface >() );
563 }
564
565 //==================================================================================================
566 struct ODisposingListener : public WeakImplHelper1< XEventListener >
567 {
568 Condition cDisposed;
569
570 // XEventListener
571 virtual void SAL_CALL disposing( const EventObject & rEvt )
572 throw (RuntimeException);
573
574 //----------------------------------------------------------------------------------------------
575 static void waitFor( const Reference< XComponent > & xComp );
576 };
577 //__________________________________________________________________________________________________
disposing(const EventObject &)578 void ODisposingListener::disposing( const EventObject & )
579 throw (RuntimeException)
580 {
581 cDisposed.set();
582 }
583 //--------------------------------------------------------------------------------------------------
waitFor(const Reference<XComponent> & xComp)584 void ODisposingListener::waitFor( const Reference< XComponent > & xComp )
585 {
586 ODisposingListener * pListener = new ODisposingListener();
587 Reference< XEventListener > xListener( pListener );
588
589 xComp->addEventListener( xListener );
590 pListener->cDisposed.wait();
591 }
592
593
594 //##################################################################################################
595 //##################################################################################################
596 //##################################################################################################
597
598
599 //##################################################################################################
600 } // namespace unoexe
601
602 using namespace unoexe;
603
604 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,)
605 {
606 if (argc <= 1)
607 {
608 out( arUsingText );
609 return 0;
610 }
611
612 sal_Int32 nRet = 0;
613 Reference< XComponentContext > xContext;
614
615
616 try
617 {
618 OUString aImplName, aLocation, aServiceName, aUnoUrl;
619 vector< OUString > aReadOnlyRegistries;
620 Sequence< OUString > aParams;
621 sal_Bool bSingleAccept = sal_False;
622 sal_Bool bSingleInstance = sal_False;
623
624 //#### read command line arguments #########################################################
625
626 bool bOldRegistryMimic = false;
627 bool bNewRegistryMimic = false;
628 OUString aReadWriteRegistry;
629
630 sal_Int32 nPos = 0;
631 sal_Int32 nCount = (sal_Int32)rtl_getAppCommandArgCount();
632 // read up to arguments
633 while (nPos < nCount)
634 {
635 OUString arg;
636
637 rtl_getAppCommandArg(nPos, &arg.pData);
638
639 const OUString dashdash = OUString(RTL_CONSTASCII_USTRINGPARAM("--"));
640 if (dashdash == arg)
641 {
642 ++nPos;
643 break;
644 }
645
646 if (readOption( &aImplName, "c", &nPos, arg) ||
647 readOption( &aLocation, "l", &nPos, arg) ||
648 readOption( &aServiceName, "s", &nPos, arg) ||
649 readOption( &aUnoUrl, "u", &nPos, arg) ||
650 readOption( &s_quiet, "quiet", &nPos, arg) ||
651 readOption( &bSingleAccept, "singleaccept", &nPos, arg) ||
652 readOption( &bSingleInstance, "singleinstance", &nPos, arg))
653 {
654 continue;
655 }
656 OUString aRegistry;
657 if (readOption( &aRegistry, "ro", &nPos, arg))
658 {
659 aReadOnlyRegistries.push_back( aRegistry );
660 bNewRegistryMimic = true;
661 continue;
662 }
663 if (readOption( &aReadWriteRegistry, "rw", &nPos, arg))
664 {
665 bNewRegistryMimic = true;
666 continue;
667 }
668 if (readOption( &aRegistry, "r", &nPos, arg))
669 {
670 aReadOnlyRegistries.push_back( aRegistry );
671 aReadWriteRegistry = aRegistry;
672 out( "\n> warning: DEPRECATED use of option -r, use -ro or -rw!" );
673 bOldRegistryMimic = true;
674 continue;
675 }
676
677 // else illegal argument
678 OUStringBuffer buf( 64 );
679 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"") );
680 buf.append(arg);
681 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
682 throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
683 }
684
685 if (bOldRegistryMimic) // last one was set to be read-write
686 {
687 aReadOnlyRegistries.pop_back();
688 if (bOldRegistryMimic && bNewRegistryMimic)
689 {
690 throw RuntimeException(
691 OUString( RTL_CONSTASCII_USTRINGPARAM("mixing with DEPRECATED registry options!") ),
692 Reference< XInterface >() );
693 }
694 }
695
696 if ((aImplName.getLength() != 0) && (aServiceName.getLength() != 0))
697 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component exOR service name!" ) ), Reference< XInterface >() );
698 if (aImplName.getLength() == 0 && aServiceName.getLength() == 0)
699 {
700 if (! aUnoUrl.endsWithIgnoreAsciiCaseAsciiL(
701 RTL_CONSTASCII_STRINGPARAM(";uno.ComponentContext") ))
702 throw RuntimeException(
703 OUString( RTL_CONSTASCII_USTRINGPARAM(
704 "expected UNO-URL with instance name "
705 "uno.ComponentContext!") ),
706 Reference<XInterface>() );
707 if (bSingleInstance)
708 throw RuntimeException(
709 OUString( RTL_CONSTASCII_USTRINGPARAM(
710 "unexpected option --singleinstance!") ),
711 Reference<XInterface>() );
712 }
713 if (aImplName.getLength() && !aLocation.getLength())
714 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component location!" ) ), Reference< XInterface >() );
715 if (aServiceName.getLength() && aLocation.getLength())
716 out( "\n> warning: service name given, will ignore location!" );
717
718 // read component params
719 aParams.realloc( nCount - nPos );
720 OUString * pParams = aParams.getArray();
721
722 sal_Int32 nOffset = nPos;
723 for ( ; nPos < nCount; ++nPos )
724 {
725 if (rtl_getAppCommandArg( nPos, &pParams[nPos -nOffset].pData )
726 != osl_Process_E_None)
727 {
728 OSL_ASSERT(false);
729 }
730 }
731
732 if (aReadOnlyRegistries.size() > 0 ||
733 aReadWriteRegistry.getLength() > 0)
734 {
735 //#### create registry #############################################
736
737 Reference< XSimpleRegistry > xRegistry;
738
739 // ReadOnly registries
740 for ( size_t nReg = 0; nReg < aReadOnlyRegistries.size(); ++nReg )
741 {
742 #if OSL_DEBUG_LEVEL > 1
743 out( "\n> trying to open ro registry: " );
744 out( OUStringToOString(
745 aReadOnlyRegistries[ nReg ],
746 RTL_TEXTENCODING_ASCII_US ).getStr() );
747 #endif
748 Reference< XSimpleRegistry > xNewReg(
749 openRegistry(
750 aReadOnlyRegistries[ nReg ], sal_True, sal_False ) );
751 if (xNewReg.is())
752 xRegistry = (xRegistry.is() ? nestRegistries(
753 xNewReg, xRegistry ) : xNewReg);
754 }
755 if (aReadWriteRegistry.getLength())
756 {
757 #if OSL_DEBUG_LEVEL > 1
758 out( "\n> trying to open rw registry: " );
759 out( OUStringToOString(
760 aReadWriteRegistry,
761 RTL_TEXTENCODING_ASCII_US ).getStr() );
762 #endif
763 // ReadWrite registry
764 Reference< XSimpleRegistry > xNewReg(
765 openRegistry( aReadWriteRegistry, sal_False, sal_True ) );
766 if (xNewReg.is())
767 xRegistry = (xRegistry.is()
768 ? nestRegistries( xNewReg, xRegistry )
769 : xNewReg);
770 }
771
772 OSL_ASSERT( xRegistry.is() );
773 xContext = bootstrap_InitialComponentContext( xRegistry );
774 }
775 else // defaulting
776 {
777 xContext = defaultBootstrap_InitialComponentContext();
778 }
779
780 //#### accept, instanciate, etc. ###########################################################
781
782 if (aUnoUrl.getLength()) // accepting connections
783 {
784 sal_Int32 nIndex = 0, nTokens = 0;
785 do { aUnoUrl.getToken( 0, ';', nIndex ); nTokens++; } while( nIndex != -1 );
786 if (nTokens != 3 || aUnoUrl.getLength() < 10 ||
787 !aUnoUrl.copy( 0, 4 ).equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("uno:") ) ))
788 {
789 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal uno url given!" ) ), Reference< XInterface >() );
790 }
791 nIndex = 0;
792 OUString aConnectDescr( aUnoUrl.getToken( 0, ';', nIndex ).copy( 4 ) ); // uno:CONNECTDESCR;iiop;InstanceName
793 OUString aInstanceName( aUnoUrl.getToken( 1, ';', nIndex ) );
794
795 Reference< XAcceptor > xAcceptor;
796 createInstance(
797 xAcceptor, xContext,
798 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor") ) );
799
800 // init params
801 Sequence< Any > aInitParams( aParams.getLength() );
802 const OUString * p = aParams.getConstArray();
803 Any * pInitParams = aInitParams.getArray();
804 for ( sal_Int32 i = aParams.getLength(); i--; )
805 {
806 pInitParams[i] = makeAny( p[i] );
807 }
808
809 // instance provider
810 Reference< XInstanceProvider > xInstanceProvider( new OInstanceProvider(
811 xContext, aImplName, aLocation, aServiceName, aInitParams,
812 bSingleInstance, aInstanceName ) );
813
814 nIndex = 0;
815 OUString aUnoUrlToken( aUnoUrl.getToken( 1, ';', nIndex ) );
816 for (;;)
817 {
818 // accepting
819 out( "\n> accepting " );
820 out( aConnectDescr );
821 out( "..." );
822 Reference< XConnection > xConnection( xAcceptor->accept( aConnectDescr ) );
823 out( "connection established." );
824
825 Reference< XBridgeFactory > xBridgeFactory;
826 createInstance(
827 xBridgeFactory, xContext,
828 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ) );
829
830 // bridge
831 Reference< XBridge > xBridge( xBridgeFactory->createBridge(
832 OUString(), aUnoUrlToken,
833 xConnection, xInstanceProvider ) );
834
835 if (bSingleAccept)
836 {
837 Reference< XComponent > xComp( xBridge, UNO_QUERY );
838 if (! xComp.is())
839 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("bridge factory does not export interface \"com.sun.star.lang.XComponent\"!" ) ), Reference< XInterface >() );
840 ODisposingListener::waitFor( xComp );
841 break;
842 }
843 }
844 }
845 else // no uno url
846 {
847 Reference< XInterface > xInstance;
848 if (aImplName.getLength()) // manually via loader
849 xInstance = loadComponent( xContext, aImplName, aLocation );
850 else // via service manager
851 createInstance( xInstance, xContext, aServiceName );
852
853 // execution
854 Reference< XMain > xMain( xInstance, UNO_QUERY );
855 if (xMain.is())
856 {
857 nRet = xMain->run( aParams );
858 }
859 else
860 {
861 Reference< XComponent > xComp( xInstance, UNO_QUERY );
862 if (xComp.is())
863 xComp->dispose();
864 throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("component does not export interface interface \"com.sun.star.lang.XMain\"!" ) ), Reference< XInterface >() );
865 }
866 }
867 }
868 catch (Exception & rExc)
869 {
870 out( "\n> error: " );
871 out( rExc.Message );
872 out( "\n> dying..." );
873 nRet = 1;
874 }
875
876 // cleanup
877 Reference< XComponent > xComp( xContext, UNO_QUERY );
878 if (xComp.is())
879 xComp->dispose();
880
881 out( "\n" );
882 return nRet;
883 }
884
885
886
887