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 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include <vector>
28 
29 #include "sal/main.h"
30 #include <rtl/strbuf.hxx>
31 #include <rtl/ustrbuf.hxx>
32 
33 #include <cppuhelper/servicefactory.hxx>
34 #include <cppuhelper/shlib.hxx>
35 
36 #include <com/sun/star/container/XSet.hpp>
37 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
38 #include <com/sun/star/registry/XImplementationRegistration2.hpp>
39 #include <com/sun/star/registry/XSimpleRegistry.hpp>
40 #include <com/sun/star/lang/XComponent.hpp>
41 
42 #include <algorithm>
43 #include <osl/process.h>
44 #include <osl/diagnose.h>
45 #include <osl/thread.h>
46 #include <osl/file.hxx>
47 
48 #ifdef SAL_UNX
49 #define SEPARATOR '/'
50 #else
51 #define SEPARATOR '\\'
52 #endif
53 
54 using namespace ::rtl;
55 using namespace ::osl;
56 using namespace ::cppu;
57 using namespace ::std;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::registry;
61 using com::sun::star::container::XSet;
62 using com::sun::star::container::XContentEnumerationAccess;
63 using com::sun::star::container::XEnumeration;
64 
65 namespace {
66 
replacePrefix(OUString const & url,OUString const & prefix)67 OUString replacePrefix(OUString const & url, OUString const & prefix) {
68     sal_Int32 i = url.lastIndexOf('/');
69     // Backward compatibility with stoc/source/implementationregistration/
70     // implreg.cxx:1.27 l. 1892:
71     if (i == -1) {
72         i = url.lastIndexOf('\\');
73     }
74     return prefix + url.copy(i + 1);
75 }
76 
77 }
78 
isFileUrl(const OUString & fileName)79 sal_Bool isFileUrl(const OUString& fileName)
80 {
81     if (fileName.indexOf(OUString::createFromAscii("file://")) == 0 )
82         return sal_True;
83     return sal_False;
84 }
85 
convertToFileUrl(const OUString & fileName)86 OUString convertToFileUrl(const OUString& fileName)
87 {
88     if ( isFileUrl(fileName) )
89     {
90         return fileName;
91     }
92 
93     OUString uUrlFileName;
94     if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
95     {
96         OUString uWorkingDir;
97         if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
98             OSL_ASSERT(false);
99         }
100         if (FileBase::getAbsoluteFileURL(uWorkingDir, fileName, uUrlFileName)
101             != FileBase::E_None)
102         {
103             OSL_ASSERT(false);
104         }
105     } else
106     {
107         if (FileBase::getFileURLFromSystemPath(fileName, uUrlFileName)
108             != FileBase::E_None)
109         {
110             OSL_ASSERT(false);
111         }
112     }
113 
114     return uUrlFileName;
115 }
usingRegisterImpl()116 static void usingRegisterImpl()
117 {
118 	fprintf(stderr, "usage: regcomp -register|revoke -r registryfile -c locationUrl [-br registryfile] [-l componentLoaderUrl] [-s] [-classpath path]\n");
119 	fprintf(stderr, " Parameters:\n");
120 	fprintf(stderr, "  -register\n"
121                     "        register a new component.\n");
122 	fprintf(stderr, "  -revoke\n"
123                     "        revoke a component.\n");
124 	fprintf(stderr, "  -br registryfile\n"
125                     "        the name of the registry used for bootstrapping\n"
126                     "        regcomp. The option can be given twice, each\n"
127                     "        one followed by exactly one registry file.\n"
128                     "        The registries are used to access both types and\n"
129                     "        registered components.\n");
130 	fprintf(stderr, "  -r registryfile\n"
131                     "        the name of the target registry (will be created\n"
132                     "        if it does not exists). The file name may match\n"
133                     "        with one of the filenames given with the -br option.\n");
134 	fprintf(stderr, "  -c locationUrls\n"
135                     "        the location of a component (a url to a shared\n"
136                     "        library or a absolute url to a .jar file) or a\n"
137                     "        list of urls separated by ';' or ' '. Note if a\n"
138                     "        list of urls is specified, the components must\n"
139                     "        all need the same loader (quoting is possible with\n"
140                     "        \\ or \"\").\n");
141 	fprintf(stderr, "  -l componentLoaderUrl\n"
142                     "        the name of the needed loader. If no loader is\n"
143                     "        specified and the components have a .jar suffix,\n"
144                     "        the default is com.sun.star.loader.Java2.\n"
145 					"        Otherwise, the default is\n"
146                     "        com.sun.star.loader.SharedLibrary\n"
147                     "  -s\n"
148                     "        silent, regcomp prints messages only on error.\n"
149                     "  -wop\n"
150                     "        register the component name only without path\n"
151                     "  -wop=prefix\n"
152                     "        register the component name with path replaced\n"
153                     "        by given prefix\n"
154                     "  -classpath path\n"
155                     "        sets the java classpath to path (overwriting the\n"
156                     "        current classpath environment variable). Note that\n"
157                     "        in case you start regcomp e.g. within an office\n"
158                     "        environment, the classpath entries in the\n"
159                     "        configuration still have precedence over this\n"
160                     "        option.\n");
161 }
162 
163 class IllegalArgument
164 {
165 public:
IllegalArgument(const OString & rMessage)166 	IllegalArgument(const OString& rMessage)
167 		: m_message(rMessage)
168 		{}
169 
170 	OString m_message;
171 };
172 
173 struct Options
174 {
OptionsOptions175 	Options()
176 		: bRegister(sal_False)
177 		, bRevoke(sal_False)
178         , bSilent( sal_False )
179         , bPrefix( sal_False )
180 		{}
181 
182 	sal_Bool bRegister;
183 	sal_Bool bRevoke;
184     sal_Bool bSilent;
185 	sal_Bool bPrefix;
186     OUString sPrefix;
187 	OUString sProgramName;
188 	OUString sBootRegName;
189     OUString sBootRegName2;
190 	OUString sRegName;
191 	OUString sComponentUrls;
192 	OUString sLoaderName;
193 };
194 
parseOptions(int ac,char * av[],Options & rOptions,sal_Bool bCmdFile)195 sal_Bool parseOptions(int ac, char* av[], Options& rOptions, sal_Bool bCmdFile)
196 	throw( IllegalArgument )
197 {
198 	sal_Bool 	ret = sal_True;
199 	sal_uInt16	i=0;
200     sal_Bool bLoaderExplicitlyGiven = sal_False;
201 
202 	rOptions.sProgramName = OUString::createFromAscii(av[i++]);
203 
204 	if (!bCmdFile)
205 	{
206 		bCmdFile = sal_True;
207 
208 		if (ac < 2)
209 		{
210 			usingRegisterImpl();
211 			ret = sal_False;
212 		}
213 	}
214 
215 	for (; i < ac; i++)
216 	{
217 		if (av[i][0] == '-')
218 		{
219 			switch (av[i][1])
220 			{
221 				case 'r':
222 					if (strcmp(av[i], "-register") == 0)
223 					{
224 						rOptions.bRegister = sal_True;
225 					} else
226 					if (strcmp(av[i], "-revoke") == 0)
227 					{
228 						rOptions.bRevoke = sal_True;
229 					} else
230 					if (av[i][2] == '\0')
231 					{
232 						if (i < ac - 1 && av[i+1][0] != '-')
233 						{
234 							i++;
235 							rOptions.sRegName = OStringToOUString(av[i], osl_getThreadTextEncoding());
236 						} else
237 						{
238 							OString tmp("'-r', please check");
239 							if (i <= ac - 1)
240 							{
241 								tmp += " your input '" + OString(av[i+1]) + "'";
242 							}
243 							throw IllegalArgument(tmp);
244 						}
245 					} else
246 					{
247 						rOptions.sRegName = OStringToOUString(av[i]+2, osl_getThreadTextEncoding());
248 					}
249 					break;
250 				case 'b':
251 					if (av[i][2] != 'r')
252 					{
253 						OString tmp("'-b', invalid option!");
254 						throw IllegalArgument(tmp);
255 					}
256 					if (av[i][3] == '\0')
257 					{
258 						if (i < ac - 1 && av[i+1][0] != '-')
259 						{
260 							i++;
261                             OUString regName = OStringToOUString(av[i], osl_getThreadTextEncoding());
262                             if( ! rOptions.sBootRegName.getLength() )
263                             {
264                                 rOptions.sBootRegName = regName;
265                             }
266                             else
267                             {
268                                 rOptions.sBootRegName2 = regName;
269                             }
270 						} else
271 						{
272 							OString tmp("'-br', please check");
273 							if (i <= ac - 1)
274 							{
275 								tmp += " your input '" + OString(av[i+1]) + "'";
276 							}
277 							throw IllegalArgument(tmp);
278 						}
279 					} else
280 					{
281 						rOptions.sBootRegName = OStringToOUString(av[i]+3, osl_getThreadTextEncoding());
282 					}
283 					break;
284 				case 'c':
285 				{
286 					OUString sUrls;
287 					if (av[i][2] == '\0')
288 					{
289 						if (i < ac - 1 && av[i+1][0] != '-')
290 						{
291 							i++;
292 							sUrls = OStringToOUString(av[i], osl_getThreadTextEncoding());
293 						} else
294 						{
295 							OString tmp("'-c', please check");
296 							if (i <= ac - 1)
297 							{
298 								tmp += " your input '" + OString(av[i+1]) + "'";
299 							}
300 							throw IllegalArgument(tmp);
301 						}
302 					}
303                     else if( 0 == strncmp( av[i] , "-classpath" ,10 ) )
304                     {
305                         i++;
306                         if( i < ac )
307                         {
308                             rtl::OUString envVar(RTL_CONSTASCII_USTRINGPARAM("CLASSPATH"));
309                             rtl::OUString envValue(av[i], strlen(av[i]), osl_getThreadTextEncoding());
310                             osl_setEnvironment(envVar.pData, envValue.pData);
311                         }
312                         break;
313                     }
314                     else
315 					{
316 						sUrls = OStringToOUString(av[i]+2, osl_getThreadTextEncoding());
317 					}
318 
319                     if (rOptions.sComponentUrls.getLength())
320 					{
321 						OUString tmp(rOptions.sComponentUrls + OUString(";", 1, osl_getThreadTextEncoding()) + sUrls);
322 						rOptions.sComponentUrls = tmp;
323 					} else
324 					{
325 						rOptions.sComponentUrls = sUrls;
326 					}
327 					break;
328 				}
329 				case 'l':
330 				{
331 					if (av[i][2] == '\0')
332 					{
333 						if (i < ac - 1 && av[i+1][0] != '-')
334 						{
335 							i++;
336 							rOptions.sLoaderName = OUString::createFromAscii(av[i]);
337                             bLoaderExplicitlyGiven = sal_True;
338 						} else
339 						{
340 							OString tmp("'-l', please check");
341 							if (i <= ac - 1)
342 							{
343 								tmp += " your input '" + OString(av[i+1]) + "'";
344 							}
345 							throw IllegalArgument(tmp);
346 						}
347 					} else
348 					{
349                         bLoaderExplicitlyGiven = sal_True;
350 						rOptions.sLoaderName = OUString::createFromAscii(av[i]+2);
351 					}
352 					break;
353 				}
354                 case 's':
355                 {
356                     if( av[i][2] == 0 )
357                     {
358                         rOptions.bSilent = sal_True;
359                     }
360                     else
361                     {
362                         rtl::OStringBuffer buf;
363                         buf.append( "Unknown error " );
364                         buf.append( av[i] );
365                         throw IllegalArgument( av[i] );
366                     }
367                     break;
368                 }
369                 case 'e':
370                 {
371                     if( av[i][2] == 'n' && av[i][3] == 'v' && av[i][4] == ':' )
372                     {
373                         // bootstrap variable, ignore it
374                         break;
375                     }
376                 }
377                 case 'w':
378                 {
379                     if (strcmp(av[i], "-wop") == 0)
380 					{
381 						rOptions.bPrefix = sal_True;
382                         rOptions.sPrefix = OUString();
383                             // in case there are multiple -wops
384                         break;
385 					}
386                     else if (
387                         strncmp(av[i], "-wop=", RTL_CONSTASCII_LENGTH("-wop="))
388                         == 0)
389                     {
390                         rOptions.bPrefix = sal_True;
391                         rOptions.sPrefix = OStringToOUString(
392                             av[i] + RTL_CONSTASCII_LENGTH("-wop="),
393                             osl_getThreadTextEncoding());
394                         break;
395                     }
396                 }
397                 default:
398                 {
399                     OString tmp( "unknown option " );
400                     tmp += av[i];
401                     throw IllegalArgument( tmp );
402                 }
403 			}
404 		} else
405 		{
406 			if (av[i][0] == '@')
407 			{
408 				FILE* cmdFile = fopen(av[i]+1, "r");
409 		  		if( cmdFile == NULL )
410       			{
411 					usingRegisterImpl();
412 					ret = sal_False;
413 				} else
414 				{
415                     fseek( cmdFile , 0 , SEEK_END );
416                     sal_Int32 nLen = ftell( cmdFile);
417                     fseek( cmdFile, 0, SEEK_SET );
418 
419                     // 2 chars per string is a upper limit for the number of
420                     // substrings ( at least one separator char needed for fscanf).
421 					char ** rargv = (char **)rtl_allocateMemory( nLen * sizeof( char* ) /2);
422                     if( ! rargv )
423                     {
424                         OStringBuffer buf;
425                         buf.append( "Not enough memory for reading command file " );
426                         buf.append( av[i] +1 );
427                         buf.append( " with length " );
428                         buf.append( nLen );
429                         buf.append( "." );
430                         throw IllegalArgument( buf.makeStringAndClear() );
431                     }
432 					char *buffer = ( char * )rtl_allocateMemory( nLen +1 );
433                     if( ! buffer )
434                     {
435                         OStringBuffer buf;
436                         buf.append( "Not enough memory for reading command file " );
437                         buf.append( av[i] +1 );
438                         buf.append( " with length " );
439                         buf.append( nLen );
440                         buf.append( "." );
441                         throw IllegalArgument( buf.makeStringAndClear() );
442                     }
443 
444                     // we start at one to omit argv[0]
445                     sal_Int32 rargc = 1;
446                     rargv[0] = av[0];
447 					while ( fscanf(cmdFile, "%s", buffer) != EOF )
448 					{
449 						rargv[rargc]= (char * )rtl_allocateMemory( strlen( buffer ) +1 );
450                         if( ! rargv[rargc] )
451                         {
452                             OStringBuffer buf;
453                             buf.append( "Not enough memory for reading command file " );
454                             buf.append( av[i] +1 );
455                             buf.append( " with length " );
456                             buf.append( nLen );
457                             buf.append( "." );
458                             throw IllegalArgument( buf.makeStringAndClear() );
459                         }
460                         strcpy( rargv[rargc] , buffer ); // #100211# - checked
461 						rargc++;
462 					}
463 					fclose(cmdFile);
464 
465 					parseOptions(rargc, rargv, rOptions, bCmdFile);
466 
467 					for (long j=1; j < rargc; j++)
468 					{
469 						rtl_freeMemory(rargv[j]);
470 					}
471                     rtl_freeMemory( buffer );
472                     rtl_freeMemory( rargv );
473 				}
474 			} else
475 			{
476 				usingRegisterImpl();
477 				ret = sal_False;
478 			}
479 		}
480 	}
481 
482     if( ! bLoaderExplicitlyGiven )
483     {
484         if ( rOptions.sComponentUrls.getLength() > 4 &&
485              rOptions.sComponentUrls.matchAsciiL(
486                  ".jar" , 4 , rOptions.sComponentUrls.getLength() - 4 ) )
487         {
488             if( ! rOptions.bSilent )
489             {
490                 printf( "using loader com.sun.star.loader.Java2\n" );
491             }
492             rOptions.sLoaderName = OUString(
493                 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java2"));
494         }
495         else
496         {
497             rOptions.sLoaderName = OUString(
498                 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") );
499         }
500     }
501 
502 	return ret;
503 }
504 
505 
506 struct DoIt
507 {
508 	sal_Bool                                _bRegister;
509 	sal_Bool                                _bRevoke;
510     sal_Bool                                _bSilent;
511     sal_Bool                                _bPrefix;
512     OUString                                _sPrefix;
513 	OString 	                            _sRegName;
514 	OUString                                _sLoaderName;
515 	Reference<XImplementationRegistration2> _xImplRegistration;
516 	Reference<XSimpleRegistry> 		        _xReg;
517 	sal_uInt32                            * _exitCode;
518 
519 	DoIt(sal_Bool bRegister,
520 		 sal_Bool bRevoke,
521          sal_Bool bSilent,
522          sal_Bool bPrefix,
523          const OUString & sPrefix,
524 		 const Reference<XSimpleRegistry> & xReg,
525 		 const OString & sRegName,
526 		 const Reference<XImplementationRegistration2> & xImplRegistration,
527 		 const OUString & sLoaderName,
528 		 sal_uInt32 * exitCode)
529 		throw();
530 
531 	void operator()(const OUString & url) throw();
532 };
533 
DoIt(sal_Bool bRegister,sal_Bool bRevoke,sal_Bool bSilent,sal_Bool bPrefix,const OUString & sPrefix,const Reference<XSimpleRegistry> & xReg,const OString & sRegName,const Reference<XImplementationRegistration2> & xImplRegistration,const OUString & sLoaderName,sal_uInt32 * exitCode)534 DoIt::DoIt(sal_Bool bRegister,
535 		   sal_Bool bRevoke,
536            sal_Bool bSilent,
537            sal_Bool bPrefix,
538            const OUString & sPrefix,
539 		   const Reference<XSimpleRegistry> & xReg,
540 		   const OString & sRegName,
541 		   const Reference<XImplementationRegistration2> & xImplRegistration,
542 		   const OUString & sLoaderName,
543 		   sal_uInt32 * exitCode) throw()
544 	: _bRegister(bRegister),
545 	  _bRevoke(bRevoke),
546       _bSilent( bSilent ),
547       _bPrefix( bPrefix ),
548       _sPrefix( sPrefix ),
549 	  _sRegName(sRegName),
550 	  _sLoaderName(sLoaderName),
551 	  _xImplRegistration(xImplRegistration),
552 	  _xReg(xReg),
553 	  _exitCode(exitCode)
554 {}
555 
operator ()(const OUString & url)556 void DoIt::operator() (const OUString & url) throw()
557 {
558 	OString sUrl = OUStringToOString(url, osl_getThreadTextEncoding());
559 
560 	if (_bRegister)
561 	{
562 		try
563 		{
564             Reference<XImplementationRegistration2> _xImplRegistration2(_xImplRegistration, UNO_QUERY);
565             if ( _bPrefix ) {
566                 _xImplRegistration->registerImplementationWithLocation(
567                     _sLoaderName, url, replacePrefix(url, _sPrefix), _xReg);
568             } else {
569                 _xImplRegistration->registerImplementation(_sLoaderName, url, _xReg);
570             }
571 
572             if ( ! _bSilent )
573             {
574                 fprintf(stderr, "register component '%s' in registry '%s' successful!\n", sUrl.getStr(), _sRegName.getStr());
575             }
576 
577 		}
578 		catch(CannotRegisterImplementationException & cannotRegisterImplementationException) {
579 			OString aMessage(OUStringToOString(cannotRegisterImplementationException.Message, RTL_TEXTENCODING_ASCII_US));
580 			fprintf(stderr, "register component '%s' in registry '%s' failed!\n", sUrl.getStr(), _sRegName.getStr());
581 			fprintf(stderr, "error (CannotRegisterImplementationException): %s\n", aMessage.getStr());
582 
583 			++ (*_exitCode);
584 		}
585         catch( RuntimeException & e )
586         {
587 			OString aMessage(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
588 			fprintf(stderr, "register component '%s' in registry '%s' failed!\n", sUrl.getStr(), _sRegName.getStr());
589 			fprintf(stderr, "error (RuntimeException): %s\n", aMessage.getStr());
590 
591 			++ (*_exitCode);
592         }
593 	}
594 	else if(_bRevoke)
595 	{
596         try
597         {
598             sal_Bool bRet = _xImplRegistration->revokeImplementation(url, _xReg);
599 
600             if (bRet)
601             {
602                 if ( ! _bSilent )
603                     fprintf(stderr, "revoke component '%s' from registry '%s' successful!\n", sUrl.getStr(), _sRegName.getStr());
604             }
605             else
606             {
607                 fprintf(stderr, "revoke component '%s' from registry '%s' failed!\n", sUrl.getStr(), _sRegName.getStr());
608                 ++ (*_exitCode);
609             }
610         }
611         catch( RuntimeException & e )
612         {
613 			OString aMessage(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US));
614             fprintf( stderr,
615                      "revoke component '%s' from registry '%s' failed!\n",
616                      sUrl.getStr(),
617                      _sRegName.getStr() );
618             fprintf( stderr, "RuntimeException: %s\n" , aMessage.getStr());
619             ++ (*_exitCode);
620         }
621 	}
622 }
623 
hasService(const Reference<XMultiServiceFactory> & xSMgr,const sal_Char * service)624 static bool hasService(
625     const Reference< XMultiServiceFactory > &xSMgr,
626     const sal_Char * service )
627 {
628     bool ret = false;
629 
630     Reference< XContentEnumerationAccess > access( xSMgr, UNO_QUERY );
631     if( access.is( ))
632     {
633         Reference< XEnumeration > enumeration = access->createContentEnumeration(
634             OUString::createFromAscii( service ) );
635 
636         if( enumeration.is() && enumeration->hasMoreElements() )
637         {
638             ret = true;
639         }
640     }
641     return ret;
642 }
643 
bootstrap(Options & opt,Reference<XMultiServiceFactory> & xSMgr,Reference<XSimpleRegistry> & reg)644 static void bootstrap(
645     Options & opt ,
646     Reference< XMultiServiceFactory > &xSMgr,
647     Reference< XSimpleRegistry > & reg ) throw ( Exception )
648 {
649     if( opt.sRegName.equals( opt.sBootRegName2 ) )
650     {
651         OUString tmp2 = opt.sBootRegName;
652         opt.sBootRegName = opt.sBootRegName2;
653         opt.sBootRegName2 = tmp2;
654     }
655 
656 	if ( opt.sRegName.equals(opt.sBootRegName) )
657     {
658         if( opt.sBootRegName2.getLength() )
659         {
660             xSMgr = createRegistryServiceFactory(
661                 convertToFileUrl(opt.sRegName),
662                 convertToFileUrl(opt.sBootRegName2),
663                 sal_False );
664         }
665         else
666         {
667             xSMgr = createRegistryServiceFactory(
668                 convertToFileUrl(opt.sRegName) , sal_False );
669         }
670     }
671     else
672 	{
673         if( opt.sBootRegName2.getLength() )
674         {
675             xSMgr = createRegistryServiceFactory(
676                 convertToFileUrl( opt.sBootRegName2 ),
677                 convertToFileUrl( opt.sBootRegName ),
678                 sal_True );
679         }
680         else if ( opt.sBootRegName.getLength() )
681         {
682             xSMgr = createRegistryServiceFactory(
683                 convertToFileUrl( opt.sBootRegName ),
684                 sal_True );
685         }
686         else
687         {
688 			xSMgr = createServiceFactory();
689         }
690 		reg = Reference< XSimpleRegistry >(
691             xSMgr->createInstance(
692                 rtl::OUString::createFromAscii("com.sun.star.registry.SimpleRegistry")), UNO_QUERY);
693 
694 		if (reg.is())
695 		{
696 			try
697 			{
698 				reg->open( convertToFileUrl(opt.sRegName), sal_False, sal_True);
699 				if (!reg->isValid())
700 				{
701 					fprintf(stderr, "ERROR: open|create registry '%s' failed!\n",
702                             OUStringToOString(opt.sRegName, osl_getThreadTextEncoding() ).getStr());
703 					exit(1);
704 				}
705 			}
706 			catch( InvalidRegistryException & e)
707 			{
708                 OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
709 				fprintf(stderr,
710                         "ERROR: create registry '%s' failed!\n"
711                         "InvalidRegistryException: %s\n",
712                          OUStringToOString( opt.sRegName, osl_getThreadTextEncoding()).getStr(),
713                         o.getStr() );
714 				exit(1);
715 			}
716 		}
717 	}
718 
719     if( ! opt.sLoaderName.compareToAscii( "com.sun.star.loader.Java2" ) &&
720         ! hasService( xSMgr, "com.sun.star.loader.Java2" ) )
721     {
722         // we know our java loader, so we check, whether a java-loader is
723         // registered
724         Reference< XInterface > r = loadSharedLibComponentFactory(
725             OUString::createFromAscii( "javavm.uno" SAL_DLLEXTENSION ),
726             OUString(),
727             OUString::createFromAscii( "com.sun.star.comp.stoc.JavaVirtualMachine" ),
728             xSMgr,
729             Reference< XRegistryKey > () );
730         Reference< XInterface > r2 = loadSharedLibComponentFactory(
731             OUString::createFromAscii( "javaloader.uno" SAL_DLLEXTENSION ),
732             OUString(),
733             OUString::createFromAscii(( "com.sun.star.comp.stoc.JavaComponentLoader" ) ),
734             xSMgr,
735             Reference< XRegistryKey > () );
736         Reference <XSet> xSet( xSMgr, UNO_QUERY );
737         if( r.is() && r2.is() && xSet.is() )
738         {
739             xSet->insert( makeAny( r ) );
740             xSet->insert( makeAny( r2 ) );
741         }
742     }
743 }
744 
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,argv)745 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
746 {
747 	sal_Bool 	bRet = sal_False;
748 	sal_uInt32 	exitCode = 0;
749 	Options	 	aOptions;
750 
751 	try
752 	{
753 		if ( !parseOptions(argc, argv, aOptions, sal_False) )
754 		{
755 			exit(1);
756 		}
757 	}
758 	catch ( IllegalArgument& e)
759 	{
760 		fprintf(stderr, "ERROR: %s\n", e.m_message.getStr());
761 		exit(1);
762 	}
763 
764     if( ! aOptions.sRegName.getLength() )
765     {
766         fprintf( stderr, "ERROR: target registry missing (-r option)\n" );
767         exit( 1 );
768     }
769 	if ( aOptions.sComponentUrls.getLength() == 0 )
770 	{
771 		fprintf(stderr, "ERROR: no component url is specified!\n");
772 		exit(1);
773 	}
774 
775 	Reference< XMultiServiceFactory >	xSMgr;
776 	Reference< XSimpleRegistry > 		xReg;
777 	try
778 	{
779         bootstrap( aOptions, xSMgr ,xReg );
780 	}
781 	catch( Exception& e )
782 	{
783 		fprintf(stderr, "ERROR: create ServiceManager failed!\n");
784 		if ( e.Message.getLength() )
785 		{
786 			fprintf(stderr, "ERROR description: %s\n",
787                     OUStringToOString(e.Message, osl_getThreadTextEncoding()).getStr());
788 		}
789 		exit(1);
790 	}
791 
792 	Reference<XImplementationRegistration2> xImplRegistration(
793         xSMgr->createInstance(
794             OUString(RTL_CONSTASCII_USTRINGPARAM(
795                          "com.sun.star.registry.ImplementationRegistration"))),
796         UNO_QUERY);
797 
798 	if (xImplRegistration.is())
799 	{
800 		sal_Int32 index = 0;
801 		vector<OUString> urls;
802 
803 		OUString urlListWithSemikolon = aOptions.sComponentUrls;
804         do {
805             OUString aToken = urlListWithSemikolon.getToken( 0, ';', index);
806             fprintf(stderr, "%s\n", OUStringToOString(aToken, osl_getThreadTextEncoding()).getStr());
807             urls.push_back(aToken);
808         } while ( index >= 0 );
809 
810 
811         OString sRegName = OUStringToOString( aOptions.sRegName, osl_getThreadTextEncoding() );
812 		if(aOptions.bRegister || aOptions.bRevoke)
813         {
814 			for_each(urls.begin(), urls.end(),
815                      DoIt(aOptions.bRegister, aOptions.bRevoke, aOptions.bSilent,
816                           aOptions.bPrefix, aOptions.sPrefix,
817                           xReg, sRegName, xImplRegistration,
818                           aOptions.sLoaderName, &exitCode));
819 		}
820 		else
821 		{
822 			++ exitCode;
823 			 usingRegisterImpl();
824 		}
825 	}
826 	else
827 	{
828 		fprintf(stderr, "Component registration service could not be loaded!\n");
829 		exitCode++;
830 	}
831 
832 	if (!bRet && xReg.is() && xReg->isValid())
833 		xReg->close();
834 
835 	Reference< XComponent > xComponent( xSMgr, UNO_QUERY );
836 	if ( xComponent.is() )
837 		xComponent->dispose();
838 
839 	return exitCode;
840 }
841 
842 
843