blob: 1b6536c6f87cb16113e4b69eee5e24d69b21d9bc [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_registry.hxx"
#include "registry/registry.hxx"
#include "registry/reflread.hxx"
#include "fileurl.hxx"
#include "options.hxx"
#include "rtl/ustring.hxx"
#include "osl/diagnose.h"
#include <stdio.h>
#include <string.h>
#include <vector>
#include <string>
using namespace rtl;
using namespace registry::tools;
#define U2S( s ) \
OUStringToOString(s, RTL_TEXTENCODING_UTF8).getStr()
#define S2U( s ) \
OStringToOUString(s, RTL_TEXTENCODING_UTF8)
class Options_Impl : public Options
{
public:
explicit Options_Impl(char const * program)
: Options (program), m_bForceOutput(false)
{}
std::string const & getIndexReg() const
{ return m_indexRegName; }
std::string const & getTypeReg() const
{ return m_typeRegName; }
bool hasBase() const
{ return (m_base.getLength() > 0); }
const OString & getBase() const
{ return m_base; }
bool forceOutput() const
{ return m_bForceOutput; }
protected:
virtual void printUsage_Impl() const;
virtual bool initOptions_Impl (std::vector< std::string > & rArgs);
std::string m_indexRegName;
std::string m_typeRegName;
OString m_base;
bool m_bForceOutput;
};
// virtual
void Options_Impl::printUsage_Impl() const
{
std::string const & rProgName = getProgramName();
fprintf(stderr,
"Usage: %s -r<filename> -o<filename> [-options] | @<filename>\n", rProgName.c_str()
);
fprintf(stderr,
" -o<filename> = filename specifies the name of the new singleton index registry.\n"
" -r<filename> = filename specifies the name of the type registry.\n"
" @<filename> = filename specifies a command file.\n"
"Options:\n"
" -b<name> = name specifies the name of a start key. The types will be searched\n"
" under this key in the type registry.\n"
" -f = force the output of all found singletons.\n"
" -h|-? = print this help message and exit.\n"
);
fprintf(stderr,
"\n%s Version 1.0\n\n", rProgName.c_str()
);
}
// virtual
bool Options_Impl::initOptions_Impl(std::vector< std::string > & rArgs)
{
std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
for (; first != last; ++first)
{
std::string option (*first);
if ((*first)[0] != '-')
{
return badOption("invalid", option.c_str());
}
switch ((*first)[1])
{
case 'r':
case 'R':
{
if (!((++first != last) && ((*first)[0] != '-')))
{
return badOption("invalid", option.c_str());
}
m_typeRegName = *first;
break;
}
case 'o':
case 'O':
{
if (!((++first != last) && ((*first)[0] != '-')))
{
return badOption("invalid", option.c_str());
}
m_indexRegName = (*first);
break;
}
case 'b':
case 'B':
{
if (!((++first != last) && ((*first)[0] != '-')))
{
return badOption("invalid", option.c_str());
}
m_base = OString((*first).c_str(), (*first).size());
break;
}
case 'f':
case 'F':
{
if ((*first).size() > 2)
{
return badOption("invalid", option.c_str());
}
m_bForceOutput = sal_True;
break;
}
case 'h':
case '?':
{
if ((*first).size() > 2)
{
return badOption("invalid", option.c_str());
}
return printUsage();
// break; // unreachable
}
default:
return badOption("unknown", option.c_str());
// break; // unreachable
}
}
return true;
}
static sal_Bool checkSingletons(Options_Impl const & options, RegistryKey& singletonKey, RegistryKey& typeKey)
{
RegValueType valueType = RG_VALUETYPE_NOT_DEFINED;
sal_uInt32 size = 0;
OUString tmpName;
sal_Bool bRet = sal_False;
RegError e = typeKey.getValueInfo(tmpName, &valueType, &size);
if ((e != REG_VALUE_NOT_EXISTS) && (e != REG_INVALID_VALUE) && (valueType == RG_VALUETYPE_BINARY))
{
std::vector< sal_uInt8 > value(size);
typeKey.getValue(tmpName, &value[0]); // @@@ broken api: write to buffer w/o buffer size.
RegistryTypeReader reader(&value[0], value.size(), sal_False);
if ( reader.isValid() && reader.getTypeClass() == RT_TYPE_SINGLETON )
{
RegistryKey entryKey;
OUString singletonName = reader.getTypeName().replace('/', '.');
if ( singletonKey.createKey(singletonName, entryKey) )
{
fprintf(stderr, "%s: could not create SINGLETONS entry for \"%s\"\n",
options.getProgramName().c_str(), U2S( singletonName ));
}
else
{
bRet = sal_True;
OUString value2 = reader.getSuperTypeName();
if ( entryKey.setValue(tmpName, RG_VALUETYPE_UNICODE,
(RegValue)value2.getStr(), sizeof(sal_Unicode)* (value2.getLength()+1)) )
{
fprintf(stderr, "%s: could not create data entry for singleton \"%s\"\n",
options.getProgramName().c_str(), U2S( singletonName ));
}
if ( options.forceOutput() )
{
fprintf(stderr, "%s: create SINGLETON entry for \"%s\" -> \"%s\"\n",
options.getProgramName().c_str(), U2S( singletonName ), U2S(value2));
}
}
}
}
RegistryKeyArray subKeys;
typeKey.openSubKeys(tmpName, subKeys);
sal_uInt32 length = subKeys.getLength();
for (sal_uInt32 i = 0; i < length; i++)
{
RegistryKey elementKey = subKeys.getElement(i);
if ( checkSingletons(options, singletonKey, elementKey) )
{
bRet = sal_True;
}
}
return bRet;
}
#if (defined UNX) || (defined OS2) || (defined __MINGW32__)
int main( int argc, char * argv[] )
#else
int _cdecl main( int argc, char * argv[] )
#endif
{
std::vector< std::string > args;
for (int i = 1; i < argc; i++)
{
int result = Options::checkArgument(args, argv[i], strlen(argv[i]));
if (result != 0)
{
// failure.
return (result);
}
}
Options_Impl options(argv[0]);
if (!options.initOptions(args))
{
options.printUsage();
return (1);
}
OUString indexRegName( convertToFileUrl(options.getIndexReg().c_str(), options.getIndexReg().size()) );
Registry indexReg;
if ( indexReg.open(indexRegName, REG_READWRITE) )
{
if ( indexReg.create(indexRegName) )
{
fprintf(stderr, "%s: open registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getIndexReg().c_str());
return (2);
}
}
OUString typeRegName( convertToFileUrl(options.getTypeReg().c_str(), options.getTypeReg().size()) );
Registry typeReg;
if ( typeReg.open(typeRegName, REG_READONLY) )
{
fprintf(stderr, "%s: open registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getTypeReg().c_str());
return (3);
}
RegistryKey indexRoot;
if ( indexReg.openRootKey(indexRoot) )
{
fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getIndexReg().c_str());
return (4);
}
RegistryKey typeRoot;
if ( typeReg.openRootKey(typeRoot) )
{
fprintf(stderr, "%s: open root key of registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getTypeReg().c_str());
return (5);
}
RegistryKey typeKey;
if ( options.hasBase() )
{
if ( typeRoot.openKey(S2U(options.getBase()), typeKey) )
{
fprintf(stderr, "%s: open base key of registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getTypeReg().c_str());
return (6);
}
}
else
{
typeKey = typeRoot;
}
RegistryKey singletonKey;
if ( indexRoot.createKey(OUString::createFromAscii("SINGLETONS"), singletonKey) )
{
fprintf(stderr, "%s: open/create SINGLETONS key of registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getIndexReg().c_str());
return (7);
}
sal_Bool bSingletonsExist = checkSingletons(options, singletonKey, typeKey);
indexRoot.releaseKey();
typeRoot.releaseKey();
typeKey.releaseKey();
singletonKey.releaseKey();
if ( indexReg.close() )
{
fprintf(stderr, "%s: closing registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getIndexReg().c_str());
return (9);
}
if ( !bSingletonsExist )
{
if ( indexReg.destroy(OUString()) )
{
fprintf(stderr, "%s: destroy registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getIndexReg().c_str());
return (10);
}
}
if ( typeReg.close() )
{
fprintf(stderr, "%s: closing registry \"%s\" failed\n",
options.getProgramName().c_str(), options.getTypeReg().c_str());
return (11);
}
}