151134e9eSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
351134e9eSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
451134e9eSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
551134e9eSAndrew Rist  * distributed with this work for additional information
651134e9eSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
751134e9eSAndrew Rist  * to you under the Apache License, Version 2.0 (the
851134e9eSAndrew Rist  * "License"); you may not use this file except in compliance
951134e9eSAndrew Rist  * with the License.  You may obtain a copy of the License at
1051134e9eSAndrew Rist  *
1151134e9eSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1251134e9eSAndrew Rist  *
1351134e9eSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1451134e9eSAndrew Rist  * software distributed under the License is distributed on an
1551134e9eSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1651134e9eSAndrew Rist  * KIND, either express or implied.  See the License for the
1751134e9eSAndrew Rist  * specific language governing permissions and limitations
1851134e9eSAndrew Rist  * under the License.
1951134e9eSAndrew Rist  *
2051134e9eSAndrew Rist  *************************************************************/
2151134e9eSAndrew Rist 
2251134e9eSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_registry.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "registry/registry.hxx"
28cdf0e10cSrcweir #include "registry/reflread.hxx"
29cdf0e10cSrcweir #include "fileurl.hxx"
30cdf0e10cSrcweir #include "options.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "rtl/ustring.hxx"
33cdf0e10cSrcweir #include "osl/diagnose.h"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <stdio.h>
36cdf0e10cSrcweir #include <string.h>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <vector>
39cdf0e10cSrcweir #include <string>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace rtl;
42cdf0e10cSrcweir using namespace registry::tools;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #define U2S( s ) \
45cdf0e10cSrcweir 	OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()
46cdf0e10cSrcweir #define S2U( s ) \
47cdf0e10cSrcweir 	OStringToOUString(s, RTL_TEXTENCODING_UTF8)
48cdf0e10cSrcweir 
49cdf0e10cSrcweir class Options_Impl : public Options
50cdf0e10cSrcweir {
51cdf0e10cSrcweir public:
Options_Impl(char const * program)52cdf0e10cSrcweir 	explicit Options_Impl(char const * program)
53cdf0e10cSrcweir 		: Options (program), m_bForceOutput(false)
54cdf0e10cSrcweir 		{}
55cdf0e10cSrcweir 
getIndexReg() const56cdf0e10cSrcweir     std::string const & getIndexReg() const
57cdf0e10cSrcweir         { return m_indexRegName; }
getTypeReg() const58cdf0e10cSrcweir     std::string const & getTypeReg() const
59cdf0e10cSrcweir 		{ return m_typeRegName; }
hasBase() const60cdf0e10cSrcweir 	bool hasBase() const
61cdf0e10cSrcweir         { return (m_base.getLength() > 0); }
getBase() const62cdf0e10cSrcweir 	const OString & getBase() const
63cdf0e10cSrcweir 		{ return m_base; }
forceOutput() const64cdf0e10cSrcweir 	bool forceOutput() const
65cdf0e10cSrcweir 		{ return m_bForceOutput; }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir protected:
68cdf0e10cSrcweir 	virtual void printUsage_Impl() const;
69cdf0e10cSrcweir     virtual bool initOptions_Impl (std::vector< std::string > & rArgs);
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     std::string m_indexRegName;
72cdf0e10cSrcweir     std::string m_typeRegName;
73cdf0e10cSrcweir 	OString		m_base;
74cdf0e10cSrcweir     bool m_bForceOutput;
75cdf0e10cSrcweir };
76cdf0e10cSrcweir 
77cdf0e10cSrcweir // virtual
printUsage_Impl() const78cdf0e10cSrcweir void Options_Impl::printUsage_Impl() const
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     std::string const & rProgName = getProgramName();
81cdf0e10cSrcweir     fprintf(stderr,
82cdf0e10cSrcweir             "Usage: %s -r<filename> -o<filename> [-options] | @<filename>\n", rProgName.c_str()
83cdf0e10cSrcweir             );
84cdf0e10cSrcweir     fprintf(stderr,
85cdf0e10cSrcweir             "    -o<filename>  = filename specifies the name of the new singleton index registry.\n"
86cdf0e10cSrcweir             "    -r<filename>  = filename specifies the name of the type registry.\n"
87cdf0e10cSrcweir             "    @<filename>   = filename specifies a command file.\n"
88cdf0e10cSrcweir             "Options:\n"
89cdf0e10cSrcweir             "    -b<name>  = name specifies the name of a start key. The types will be searched\n"
90cdf0e10cSrcweir             "                under this key in the type registry.\n"
91cdf0e10cSrcweir             "    -f        = force the output of all found singletons.\n"
92cdf0e10cSrcweir             "    -h|-?     = print this help message and exit.\n"
93cdf0e10cSrcweir             );
94cdf0e10cSrcweir     fprintf(stderr,
95cdf0e10cSrcweir             "\n%s Version 1.0\n\n", rProgName.c_str()
96cdf0e10cSrcweir             );
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir // virtual
initOptions_Impl(std::vector<std::string> & rArgs)100cdf0e10cSrcweir bool Options_Impl::initOptions_Impl(std::vector< std::string > & rArgs)
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
103cdf0e10cSrcweir     for (; first != last; ++first)
104cdf0e10cSrcweir     {
105cdf0e10cSrcweir         std::string option (*first);
106cdf0e10cSrcweir         if ((*first)[0] != '-')
107cdf0e10cSrcweir         {
108cdf0e10cSrcweir             return badOption("invalid", option.c_str());
109cdf0e10cSrcweir         }
110cdf0e10cSrcweir         switch ((*first)[1])
111cdf0e10cSrcweir         {
112cdf0e10cSrcweir         case 'r':
113cdf0e10cSrcweir         case 'R':
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
116cdf0e10cSrcweir                 {
117cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
118cdf0e10cSrcweir                 }
119*24c56ab9SHerbert Dürr                 m_typeRegName = *first;
120cdf0e10cSrcweir                 break;
121cdf0e10cSrcweir             }
122cdf0e10cSrcweir         case 'o':
123cdf0e10cSrcweir         case 'O':
124cdf0e10cSrcweir             {
125cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
126cdf0e10cSrcweir                 {
127cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
128cdf0e10cSrcweir                 }
129cdf0e10cSrcweir                 m_indexRegName = (*first);
130cdf0e10cSrcweir                 break;
131cdf0e10cSrcweir             }
132cdf0e10cSrcweir         case 'b':
133cdf0e10cSrcweir         case 'B':
134cdf0e10cSrcweir             {
135cdf0e10cSrcweir                 if (!((++first != last) && ((*first)[0] != '-')))
136cdf0e10cSrcweir                 {
137cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
138cdf0e10cSrcweir                 }
139cdf0e10cSrcweir                 m_base = OString((*first).c_str(), (*first).size());
140cdf0e10cSrcweir                 break;
141cdf0e10cSrcweir             }
142cdf0e10cSrcweir         case 'f':
143cdf0e10cSrcweir         case 'F':
144cdf0e10cSrcweir             {
145cdf0e10cSrcweir 			    if ((*first).size() > 2)
146cdf0e10cSrcweir                 {
147cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
148cdf0e10cSrcweir                 }
149cdf0e10cSrcweir                 m_bForceOutput = sal_True;
150cdf0e10cSrcweir                 break;
151cdf0e10cSrcweir             }
152cdf0e10cSrcweir         case 'h':
153cdf0e10cSrcweir         case '?':
154cdf0e10cSrcweir             {
155cdf0e10cSrcweir 			    if ((*first).size() > 2)
156cdf0e10cSrcweir                 {
157cdf0e10cSrcweir                     return badOption("invalid", option.c_str());
158cdf0e10cSrcweir                 }
159cdf0e10cSrcweir                 return printUsage();
160cdf0e10cSrcweir                 // break; // unreachable
161cdf0e10cSrcweir             }
162cdf0e10cSrcweir         default:
163cdf0e10cSrcweir             return badOption("unknown", option.c_str());
164cdf0e10cSrcweir             // break; // unreachable
165cdf0e10cSrcweir         }
166cdf0e10cSrcweir     }
167cdf0e10cSrcweir     return true;
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
checkSingletons(Options_Impl const & options,RegistryKey & singletonKey,RegistryKey & typeKey)170cdf0e10cSrcweir static sal_Bool checkSingletons(Options_Impl const & options, RegistryKey& singletonKey, RegistryKey& typeKey)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir 	RegValueType valueType = RG_VALUETYPE_NOT_DEFINED;
173cdf0e10cSrcweir 	sal_uInt32 size = 0;
174cdf0e10cSrcweir 	OUString tmpName;
175cdf0e10cSrcweir     sal_Bool bRet = sal_False;
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 	RegError e = typeKey.getValueInfo(tmpName, &valueType, &size);
178cdf0e10cSrcweir     if ((e != REG_VALUE_NOT_EXISTS) && (e != REG_INVALID_VALUE) && (valueType == RG_VALUETYPE_BINARY))
179cdf0e10cSrcweir 	{
180cdf0e10cSrcweir         std::vector< sal_uInt8 > value(size);
181cdf0e10cSrcweir         typeKey.getValue(tmpName, &value[0]); // @@@ broken api: write to buffer w/o buffer size.
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 		RegistryTypeReader reader(&value[0], value.size(), sal_False);
184cdf0e10cSrcweir 		if ( reader.isValid() && reader.getTypeClass() == RT_TYPE_SINGLETON )
185cdf0e10cSrcweir         {
186cdf0e10cSrcweir             RegistryKey entryKey;
187cdf0e10cSrcweir 			OUString    singletonName = reader.getTypeName().replace('/', '.');
188cdf0e10cSrcweir 			if ( singletonKey.createKey(singletonName, entryKey) )
189cdf0e10cSrcweir             {
190cdf0e10cSrcweir 				fprintf(stderr, "%s: could not create SINGLETONS entry for \"%s\"\n",
191cdf0e10cSrcweir 					options.getProgramName().c_str(), U2S( singletonName ));
192cdf0e10cSrcweir             }
193cdf0e10cSrcweir             else
194cdf0e10cSrcweir             {
195cdf0e10cSrcweir 				bRet = sal_True;
196cdf0e10cSrcweir                 OUString value2 = reader.getSuperTypeName();
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 				if ( entryKey.setValue(tmpName, RG_VALUETYPE_UNICODE,
199cdf0e10cSrcweir                 					   (RegValue)value2.getStr(), sizeof(sal_Unicode)* (value2.getLength()+1)) )
200cdf0e10cSrcweir 				{
201cdf0e10cSrcweir 					fprintf(stderr, "%s: could not create data entry for singleton \"%s\"\n",
202cdf0e10cSrcweir 							options.getProgramName().c_str(), U2S( singletonName ));
203cdf0e10cSrcweir 				}
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 				if ( options.forceOutput() )
206cdf0e10cSrcweir 				{
207cdf0e10cSrcweir 					fprintf(stderr, "%s: create SINGLETON entry for \"%s\" -> \"%s\"\n",
208cdf0e10cSrcweir 							options.getProgramName().c_str(), U2S( singletonName ), U2S(value2));
209cdf0e10cSrcweir             	}
210cdf0e10cSrcweir             }
211cdf0e10cSrcweir         }
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir 
214cdf0e10cSrcweir    	RegistryKeyArray subKeys;
215cdf0e10cSrcweir 	typeKey.openSubKeys(tmpName, subKeys);
216cdf0e10cSrcweir 
217cdf0e10cSrcweir 	sal_uInt32 length = subKeys.getLength();
218cdf0e10cSrcweir 	for (sal_uInt32 i = 0; i < length; i++)
219cdf0e10cSrcweir 	{
220cdf0e10cSrcweir         RegistryKey elementKey = subKeys.getElement(i);
221cdf0e10cSrcweir 		if ( checkSingletons(options, singletonKey, elementKey) )
222cdf0e10cSrcweir 		{
223cdf0e10cSrcweir 			bRet = sal_True;
224cdf0e10cSrcweir 		}
225cdf0e10cSrcweir 	}
226cdf0e10cSrcweir 	return bRet;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir #if (defined UNX) || (defined OS2) || (defined __MINGW32__)
main(int argc,char * argv[])230cdf0e10cSrcweir int main( int argc, char * argv[] )
231cdf0e10cSrcweir #else
232cdf0e10cSrcweir int _cdecl main( int argc, char * argv[] )
233cdf0e10cSrcweir #endif
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     std::vector< std::string > args;
236cdf0e10cSrcweir     for (int i = 1; i < argc; i++)
237cdf0e10cSrcweir     {
238cdf0e10cSrcweir         int result = Options::checkArgument(args, argv[i], strlen(argv[i]));
239cdf0e10cSrcweir         if (result != 0)
240cdf0e10cSrcweir         {
241cdf0e10cSrcweir             // failure.
242cdf0e10cSrcweir             return (result);
243cdf0e10cSrcweir         }
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir     Options_Impl options(argv[0]);
247cdf0e10cSrcweir     if (!options.initOptions(args))
248cdf0e10cSrcweir 	{
249cdf0e10cSrcweir         options.printUsage();
250cdf0e10cSrcweir 		return (1);
251cdf0e10cSrcweir 	}
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 	OUString indexRegName( convertToFileUrl(options.getIndexReg().c_str(), options.getIndexReg().size()) );
254cdf0e10cSrcweir 	Registry indexReg;
255cdf0e10cSrcweir 	if ( indexReg.open(indexRegName, REG_READWRITE) )
256cdf0e10cSrcweir 	{
257cdf0e10cSrcweir 		if ( indexReg.create(indexRegName) )
258cdf0e10cSrcweir 		{
259cdf0e10cSrcweir 			fprintf(stderr, "%s: open registry \"%s\" failed\n",
260cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getIndexReg().c_str());
261cdf0e10cSrcweir 			return (2);
262cdf0e10cSrcweir         }
263cdf0e10cSrcweir 	}
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 	OUString typeRegName( convertToFileUrl(options.getTypeReg().c_str(), options.getTypeReg().size()) );
266cdf0e10cSrcweir 	Registry typeReg;
267cdf0e10cSrcweir 	if ( typeReg.open(typeRegName, REG_READONLY) )
268cdf0e10cSrcweir 	{
269cdf0e10cSrcweir 		fprintf(stderr, "%s: open registry \"%s\" failed\n",
270cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
271cdf0e10cSrcweir 		return (3);
272cdf0e10cSrcweir 	}
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	RegistryKey indexRoot;
275cdf0e10cSrcweir 	if ( indexReg.openRootKey(indexRoot) )
276cdf0e10cSrcweir 	{
277cdf0e10cSrcweir 		fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
278cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
279cdf0e10cSrcweir 		return (4);
280cdf0e10cSrcweir 	}
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 	RegistryKey typeRoot;
283cdf0e10cSrcweir 	if ( typeReg.openRootKey(typeRoot) )
284cdf0e10cSrcweir 	{
285cdf0e10cSrcweir 		fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
286cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
287cdf0e10cSrcweir 		return (5);
288cdf0e10cSrcweir 	}
289cdf0e10cSrcweir 
290cdf0e10cSrcweir 	RegistryKey typeKey;
291cdf0e10cSrcweir 	if ( options.hasBase() )
292cdf0e10cSrcweir 	{
293cdf0e10cSrcweir 		if ( typeRoot.openKey(S2U(options.getBase()), typeKey) )
294cdf0e10cSrcweir 		{
295cdf0e10cSrcweir 			fprintf(stderr, "%s: open base key of registry \"%s\" failed\n",
296cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getTypeReg().c_str());
297cdf0e10cSrcweir 			return (6);
298cdf0e10cSrcweir 		}
299cdf0e10cSrcweir 	}
300cdf0e10cSrcweir     else
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir     	typeKey = typeRoot;
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	RegistryKey singletonKey;
306cdf0e10cSrcweir 	if ( indexRoot.createKey(OUString::createFromAscii("SINGLETONS"), singletonKey) )
307cdf0e10cSrcweir 	{
308cdf0e10cSrcweir 		fprintf(stderr, "%s: open/create SINGLETONS key of registry \"%s\" failed\n",
309cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
310cdf0e10cSrcweir 		return (7);
311cdf0e10cSrcweir 	}
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 	sal_Bool bSingletonsExist = checkSingletons(options, singletonKey, typeKey);
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 	indexRoot.releaseKey();
316cdf0e10cSrcweir 	typeRoot.releaseKey();
317cdf0e10cSrcweir     typeKey.releaseKey();
318cdf0e10cSrcweir     singletonKey.releaseKey();
319cdf0e10cSrcweir 	if ( indexReg.close() )
320cdf0e10cSrcweir 	{
321cdf0e10cSrcweir 		fprintf(stderr, "%s: closing registry \"%s\" failed\n",
322cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getIndexReg().c_str());
323cdf0e10cSrcweir         return (9);
324cdf0e10cSrcweir 	}
325cdf0e10cSrcweir 	if ( !bSingletonsExist )
326cdf0e10cSrcweir 	{
327cdf0e10cSrcweir 		if ( indexReg.destroy(OUString()) )
328cdf0e10cSrcweir 		{
329cdf0e10cSrcweir 			fprintf(stderr, "%s: destroy registry \"%s\" failed\n",
330cdf0e10cSrcweir 					options.getProgramName().c_str(), options.getIndexReg().c_str());
331cdf0e10cSrcweir 	        return (10);
332cdf0e10cSrcweir 		}
333cdf0e10cSrcweir 	}
334cdf0e10cSrcweir 	if ( typeReg.close() )
335cdf0e10cSrcweir 	{
336cdf0e10cSrcweir 		fprintf(stderr, "%s: closing registry \"%s\" failed\n",
337cdf0e10cSrcweir 				options.getProgramName().c_str(), options.getTypeReg().c_str());
338cdf0e10cSrcweir         return (11);
339cdf0e10cSrcweir 	}
340cdf0e10cSrcweir }
341