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