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