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