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