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: */
|