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