1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_registry.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "registry/registry.hxx"
32*cdf0e10cSrcweir #include "registry/reflread.hxx"
33*cdf0e10cSrcweir #include "fileurl.hxx"
34*cdf0e10cSrcweir #include "options.hxx"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include "rtl/ustring.hxx"
37*cdf0e10cSrcweir #include "osl/diagnose.h"
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <stdio.h>
40*cdf0e10cSrcweir #include <string.h>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <vector>
43*cdf0e10cSrcweir #include <string>
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir using namespace rtl;
46*cdf0e10cSrcweir using namespace registry::tools;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #define U2S( s ) \
49*cdf0e10cSrcweir 	OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()
50*cdf0e10cSrcweir #define S2U( s ) \
51*cdf0e10cSrcweir 	OStringToOUString(s, RTL_TEXTENCODING_UTF8)
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir class Options_Impl : public Options
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir public:
56*cdf0e10cSrcweir 	explicit Options_Impl(char const * program)
57*cdf0e10cSrcweir 		: Options (program), m_bForceOutput(false)
58*cdf0e10cSrcweir 		{}
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir     std::string const & getIndexReg() const
61*cdf0e10cSrcweir         { return m_indexRegName; }
62*cdf0e10cSrcweir     std::string const & getTypeReg() const
63*cdf0e10cSrcweir 		{ return m_typeRegName; }
64*cdf0e10cSrcweir 	bool hasBase() const
65*cdf0e10cSrcweir         { return (m_base.getLength() > 0); }
66*cdf0e10cSrcweir 	const OString & getBase() const
67*cdf0e10cSrcweir 		{ return m_base; }
68*cdf0e10cSrcweir 	bool forceOutput() const
69*cdf0e10cSrcweir 		{ return m_bForceOutput; }
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir protected:
72*cdf0e10cSrcweir 	virtual void printUsage_Impl() const;
73*cdf0e10cSrcweir     virtual bool initOptions_Impl (std::vector< std::string > & rArgs);
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir     std::string m_indexRegName;
76*cdf0e10cSrcweir     std::string m_typeRegName;
77*cdf0e10cSrcweir 	OString		m_base;
78*cdf0e10cSrcweir     bool m_bForceOutput;
79*cdf0e10cSrcweir };
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir // virtual
82*cdf0e10cSrcweir void Options_Impl::printUsage_Impl() const
83*cdf0e10cSrcweir {
84*cdf0e10cSrcweir     std::string const & rProgName = getProgramName();
85*cdf0e10cSrcweir     fprintf(stderr,
86*cdf0e10cSrcweir             "Usage: %s -r<filename> -o<filename> [-options] | @<filename>\n", rProgName.c_str()
87*cdf0e10cSrcweir             );
88*cdf0e10cSrcweir     fprintf(stderr,
89*cdf0e10cSrcweir             "    -o<filename>  = filename specifies the name of the new singleton index registry.\n"
90*cdf0e10cSrcweir             "    -r<filename>  = filename specifies the name of the type registry.\n"
91*cdf0e10cSrcweir             "    @<filename>   = filename specifies a command file.\n"
92*cdf0e10cSrcweir             "Options:\n"
93*cdf0e10cSrcweir             "    -b<name>  = name specifies the name of a start key. The types will be searched\n"
94*cdf0e10cSrcweir             "                under this key in the type registry.\n"
95*cdf0e10cSrcweir             "    -f        = force the output of all found singletons.\n"
96*cdf0e10cSrcweir             "    -h|-?     = print this help message and exit.\n"
97*cdf0e10cSrcweir             );
98*cdf0e10cSrcweir     fprintf(stderr,
99*cdf0e10cSrcweir             "\n%s Version 1.0\n\n", rProgName.c_str()
100*cdf0e10cSrcweir             );
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir // virtual
104*cdf0e10cSrcweir bool Options_Impl::initOptions_Impl(std::vector< std::string > & rArgs)
105*cdf0e10cSrcweir {
106*cdf0e10cSrcweir     std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
107*cdf0e10cSrcweir     for (; first != last; ++first)
108*cdf0e10cSrcweir     {
109*cdf0e10cSrcweir         std::string option (*first);
110*cdf0e10cSrcweir         if ((*first)[0] != '-')
111*cdf0e10cSrcweir         {
112*cdf0e10cSrcweir             return badOption("invalid", option.c_str());
113*cdf0e10cSrcweir         }
114*cdf0e10cSrcweir         switch ((*first)[1])
115*cdf0e10cSrcweir         {
116*cdf0e10cSrcweir         case 'r':
117*cdf0e10cSrcweir         case 'R':
118*cdf0e10cSrcweir             {
119*cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
120*cdf0e10cSrcweir                 {
121*cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
122*cdf0e10cSrcweir                 }
123*cdf0e10cSrcweir                 m_typeRegName = OString((*first).c_str(), (*first).size());
124*cdf0e10cSrcweir                 break;
125*cdf0e10cSrcweir             }
126*cdf0e10cSrcweir         case 'o':
127*cdf0e10cSrcweir         case 'O':
128*cdf0e10cSrcweir             {
129*cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
130*cdf0e10cSrcweir                 {
131*cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
132*cdf0e10cSrcweir                 }
133*cdf0e10cSrcweir                 m_indexRegName = (*first);
134*cdf0e10cSrcweir                 break;
135*cdf0e10cSrcweir             }
136*cdf0e10cSrcweir         case 'b':
137*cdf0e10cSrcweir         case 'B':
138*cdf0e10cSrcweir             {
139*cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
140*cdf0e10cSrcweir                 {
141*cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
142*cdf0e10cSrcweir                 }
143*cdf0e10cSrcweir                 m_base = OString((*first).c_str(), (*first).size());
144*cdf0e10cSrcweir                 break;
145*cdf0e10cSrcweir             }
146*cdf0e10cSrcweir         case 'f':
147*cdf0e10cSrcweir         case 'F':
148*cdf0e10cSrcweir             {
149*cdf0e10cSrcweir 			    if ((*first).size() > 2)
150*cdf0e10cSrcweir                 {
151*cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
152*cdf0e10cSrcweir                 }
153*cdf0e10cSrcweir                 m_bForceOutput = sal_True;
154*cdf0e10cSrcweir                 break;
155*cdf0e10cSrcweir             }
156*cdf0e10cSrcweir         case 'h':
157*cdf0e10cSrcweir         case '?':
158*cdf0e10cSrcweir             {
159*cdf0e10cSrcweir 			    if ((*first).size() > 2)
160*cdf0e10cSrcweir                 {
161*cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
162*cdf0e10cSrcweir                 }
163*cdf0e10cSrcweir                 return printUsage();
164*cdf0e10cSrcweir                 // break; // unreachable
165*cdf0e10cSrcweir             }
166*cdf0e10cSrcweir         default:
167*cdf0e10cSrcweir             return badOption("unknown", option.c_str());
168*cdf0e10cSrcweir             // break; // unreachable
169*cdf0e10cSrcweir         }
170*cdf0e10cSrcweir     }
171*cdf0e10cSrcweir     return true;
172*cdf0e10cSrcweir }
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir static sal_Bool checkSingletons(Options_Impl const & options, RegistryKey& singletonKey, RegistryKey& typeKey)
175*cdf0e10cSrcweir {
176*cdf0e10cSrcweir 	RegValueType valueType = RG_VALUETYPE_NOT_DEFINED;
177*cdf0e10cSrcweir 	sal_uInt32 size = 0;
178*cdf0e10cSrcweir 	OUString tmpName;
179*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 	RegError e = typeKey.getValueInfo(tmpName, &valueType, &size);
182*cdf0e10cSrcweir     if ((e != REG_VALUE_NOT_EXISTS) && (e != REG_INVALID_VALUE) && (valueType == RG_VALUETYPE_BINARY))
183*cdf0e10cSrcweir 	{
184*cdf0e10cSrcweir         std::vector< sal_uInt8 > value(size);
185*cdf0e10cSrcweir         typeKey.getValue(tmpName, &value[0]); // @@@ broken api: write to buffer w/o buffer size.
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir 		RegistryTypeReader reader(&value[0], value.size(), sal_False);
188*cdf0e10cSrcweir 		if ( reader.isValid() && reader.getTypeClass() == RT_TYPE_SINGLETON )
189*cdf0e10cSrcweir         {
190*cdf0e10cSrcweir             RegistryKey entryKey;
191*cdf0e10cSrcweir 			OUString    singletonName = reader.getTypeName().replace('/', '.');
192*cdf0e10cSrcweir 			if ( singletonKey.createKey(singletonName, entryKey) )
193*cdf0e10cSrcweir             {
194*cdf0e10cSrcweir 				fprintf(stderr, "%s: could not create SINGLETONS entry for \"%s\"\n",
195*cdf0e10cSrcweir 					options.getProgramName().c_str(), U2S( singletonName ));
196*cdf0e10cSrcweir             }
197*cdf0e10cSrcweir             else
198*cdf0e10cSrcweir             {
199*cdf0e10cSrcweir 				bRet = sal_True;
200*cdf0e10cSrcweir                 OUString value2 = reader.getSuperTypeName();
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 				if ( entryKey.setValue(tmpName, RG_VALUETYPE_UNICODE,
203*cdf0e10cSrcweir                 					   (RegValue)value2.getStr(), sizeof(sal_Unicode)* (value2.getLength()+1)) )
204*cdf0e10cSrcweir 				{
205*cdf0e10cSrcweir 					fprintf(stderr, "%s: could not create data entry for singleton \"%s\"\n",
206*cdf0e10cSrcweir 							options.getProgramName().c_str(), U2S( singletonName ));
207*cdf0e10cSrcweir 				}
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 				if ( options.forceOutput() )
210*cdf0e10cSrcweir 				{
211*cdf0e10cSrcweir 					fprintf(stderr, "%s: create SINGLETON entry for \"%s\" -> \"%s\"\n",
212*cdf0e10cSrcweir 							options.getProgramName().c_str(), U2S( singletonName ), U2S(value2));
213*cdf0e10cSrcweir             	}
214*cdf0e10cSrcweir             }
215*cdf0e10cSrcweir         }
216*cdf0e10cSrcweir 	}
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir    	RegistryKeyArray subKeys;
219*cdf0e10cSrcweir 	typeKey.openSubKeys(tmpName, subKeys);
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 	sal_uInt32 length = subKeys.getLength();
222*cdf0e10cSrcweir 	for (sal_uInt32 i = 0; i < length; i++)
223*cdf0e10cSrcweir 	{
224*cdf0e10cSrcweir         RegistryKey elementKey = subKeys.getElement(i);
225*cdf0e10cSrcweir 		if ( checkSingletons(options, singletonKey, elementKey) )
226*cdf0e10cSrcweir 		{
227*cdf0e10cSrcweir 			bRet = sal_True;
228*cdf0e10cSrcweir 		}
229*cdf0e10cSrcweir 	}
230*cdf0e10cSrcweir 	return bRet;
231*cdf0e10cSrcweir }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir #if (defined UNX) || (defined OS2) || (defined __MINGW32__)
234*cdf0e10cSrcweir int main( int argc, char * argv[] )
235*cdf0e10cSrcweir #else
236*cdf0e10cSrcweir int _cdecl main( int argc, char * argv[] )
237*cdf0e10cSrcweir #endif
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir     std::vector< std::string > args;
240*cdf0e10cSrcweir     for (int i = 1; i < argc; i++)
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir         int result = Options::checkArgument(args, argv[i], strlen(argv[i]));
243*cdf0e10cSrcweir         if (result != 0)
244*cdf0e10cSrcweir         {
245*cdf0e10cSrcweir             // failure.
246*cdf0e10cSrcweir             return (result);
247*cdf0e10cSrcweir         }
248*cdf0e10cSrcweir     }
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir     Options_Impl options(argv[0]);
251*cdf0e10cSrcweir     if (!options.initOptions(args))
252*cdf0e10cSrcweir 	{
253*cdf0e10cSrcweir         options.printUsage();
254*cdf0e10cSrcweir 		return (1);
255*cdf0e10cSrcweir 	}
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir 	OUString indexRegName( convertToFileUrl(options.getIndexReg().c_str(), options.getIndexReg().size()) );
258*cdf0e10cSrcweir 	Registry indexReg;
259*cdf0e10cSrcweir 	if ( indexReg.open(indexRegName, REG_READWRITE) )
260*cdf0e10cSrcweir 	{
261*cdf0e10cSrcweir 		if ( indexReg.create(indexRegName) )
262*cdf0e10cSrcweir 		{
263*cdf0e10cSrcweir 			fprintf(stderr, "%s: open registry \"%s\" failed\n",
264*cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getIndexReg().c_str());
265*cdf0e10cSrcweir 			return (2);
266*cdf0e10cSrcweir         }
267*cdf0e10cSrcweir 	}
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir 	OUString typeRegName( convertToFileUrl(options.getTypeReg().c_str(), options.getTypeReg().size()) );
270*cdf0e10cSrcweir 	Registry typeReg;
271*cdf0e10cSrcweir 	if ( typeReg.open(typeRegName, REG_READONLY) )
272*cdf0e10cSrcweir 	{
273*cdf0e10cSrcweir 		fprintf(stderr, "%s: open registry \"%s\" failed\n",
274*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
275*cdf0e10cSrcweir 		return (3);
276*cdf0e10cSrcweir 	}
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 	RegistryKey indexRoot;
279*cdf0e10cSrcweir 	if ( indexReg.openRootKey(indexRoot) )
280*cdf0e10cSrcweir 	{
281*cdf0e10cSrcweir 		fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
282*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
283*cdf0e10cSrcweir 		return (4);
284*cdf0e10cSrcweir 	}
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir 	RegistryKey typeRoot;
287*cdf0e10cSrcweir 	if ( typeReg.openRootKey(typeRoot) )
288*cdf0e10cSrcweir 	{
289*cdf0e10cSrcweir 		fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
290*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
291*cdf0e10cSrcweir 		return (5);
292*cdf0e10cSrcweir 	}
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir 	RegistryKey typeKey;
295*cdf0e10cSrcweir 	if ( options.hasBase() )
296*cdf0e10cSrcweir 	{
297*cdf0e10cSrcweir 		if ( typeRoot.openKey(S2U(options.getBase()), typeKey) )
298*cdf0e10cSrcweir 		{
299*cdf0e10cSrcweir 			fprintf(stderr, "%s: open base key of registry \"%s\" failed\n",
300*cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getTypeReg().c_str());
301*cdf0e10cSrcweir 			return (6);
302*cdf0e10cSrcweir 		}
303*cdf0e10cSrcweir 	}
304*cdf0e10cSrcweir     else
305*cdf0e10cSrcweir     {
306*cdf0e10cSrcweir     	typeKey = typeRoot;
307*cdf0e10cSrcweir     }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir 	RegistryKey singletonKey;
310*cdf0e10cSrcweir 	if ( indexRoot.createKey(OUString::createFromAscii("SINGLETONS"), singletonKey) )
311*cdf0e10cSrcweir 	{
312*cdf0e10cSrcweir 		fprintf(stderr, "%s: open/create SINGLETONS key of registry \"%s\" failed\n",
313*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
314*cdf0e10cSrcweir 		return (7);
315*cdf0e10cSrcweir 	}
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 	sal_Bool bSingletonsExist = checkSingletons(options, singletonKey, typeKey);
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 	indexRoot.releaseKey();
320*cdf0e10cSrcweir 	typeRoot.releaseKey();
321*cdf0e10cSrcweir     typeKey.releaseKey();
322*cdf0e10cSrcweir     singletonKey.releaseKey();
323*cdf0e10cSrcweir 	if ( indexReg.close() )
324*cdf0e10cSrcweir 	{
325*cdf0e10cSrcweir 		fprintf(stderr, "%s: closing registry \"%s\" failed\n",
326*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
327*cdf0e10cSrcweir         return (9);
328*cdf0e10cSrcweir 	}
329*cdf0e10cSrcweir 	if ( !bSingletonsExist )
330*cdf0e10cSrcweir 	{
331*cdf0e10cSrcweir 		if ( indexReg.destroy(OUString()) )
332*cdf0e10cSrcweir 		{
333*cdf0e10cSrcweir 			fprintf(stderr, "%s: destroy registry \"%s\" failed\n",
334*cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getIndexReg().c_str());
335*cdf0e10cSrcweir 	        return (10);
336*cdf0e10cSrcweir 		}
337*cdf0e10cSrcweir 	}
338*cdf0e10cSrcweir 	if ( typeReg.close() )
339*cdf0e10cSrcweir 	{
340*cdf0e10cSrcweir 		fprintf(stderr, "%s: closing registry \"%s\" failed\n",
341*cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
342*cdf0e10cSrcweir         return (11);
343*cdf0e10cSrcweir 	}
344*cdf0e10cSrcweir }
345