4
0
mirror of https://github.com/QuasarApp/qca.git synced 2025-05-13 11:09:34 +00:00

use q_interface for plugins, add diagnostic text

svn path=/trunk/kdesupport/qca/; revision=513017
This commit is contained in:
Justin Karneges 2006-02-24 08:08:43 +00:00
parent a7e91276cf
commit 7722e56837
7 changed files with 270 additions and 38 deletions

@ -299,6 +299,16 @@ namespace QCA
*/
QCA_EXPORT void unloadAllPlugins();
/**
* Retrieve plugin diagnostic text
*/
QCA_EXPORT QString pluginDiagnosticText();
/**
* Clear plugin diagnostic text
*/
QCA_EXPORT void clearPluginDiagnosticText();
/**
* Set a global property
*/

@ -38,16 +38,15 @@
#include <limits>
#define QCA_PLUGIN_VERSION 2
class QCA_EXPORT QCAPlugin : public QObject
{
Q_OBJECT
public:
virtual int version() const = 0;
virtual QCA::Provider *createProvider() = 0;
};
Q_DECLARE_INTERFACE(QCAPlugin, "com.affinix.qca.Plugin/1.0")
namespace QCA {
class QCA_EXPORT RandomContext : public Provider::Context

@ -5205,12 +5205,12 @@ public:
class opensslPlugin : public QCAPlugin
{
Q_OBJECT
Q_INTERFACES(QCAPlugin)
public:
virtual int version() const { return QCA_PLUGIN_VERSION; }
virtual Provider *createProvider() { return new opensslProvider; }
};
#include "qca-openssl.moc"
Q_EXPORT_PLUGIN(opensslPlugin);
Q_EXPORT_PLUGIN2(qca-openssl, opensslPlugin);

@ -282,6 +282,18 @@ void unloadAllPlugins()
global->manager.unloadAll();
}
QString pluginDiagnosticText()
{
QMutexLocker lock(&global->manager_mutex);
return global->manager.diagnosticText();
}
void clearPluginDiagnosticText()
{
QMutexLocker lock(&global->manager_mutex);
global->manager.clearDiagnosticText();
}
void setProperty(const QString &name, const QVariant &value)
{
QMutexLocker lock(&global->manager_mutex);

@ -26,6 +26,116 @@
namespace QCA {
static ProviderManager *g_pluginman = 0;
static void logDebug(const QString &str)
{
if(g_pluginman)
g_pluginman->appendDiagnosticText(str + '\n');
}
class PluginInstance
{
private:
QPluginLoader *_loader;
QObject *_instance;
bool _ownInstance;
PluginInstance()
{
}
public:
static PluginInstance *fromFile(const QString &fname)
{
logDebug(QString("PluginInstance fromFile [%1]").arg(fname));
QPluginLoader *loader = new QPluginLoader(fname);
if(!loader->load())
{
logDebug("failed to load");
delete loader;
return 0;
}
QObject *obj = loader->instance();
if(!obj)
{
logDebug("failed to get instance");
loader->unload();
delete loader;
return 0;
}
PluginInstance *i = new PluginInstance;
i->_loader = loader;
i->_instance = obj;
i->_ownInstance = true;
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
return i;
}
static PluginInstance *fromStatic(QObject *obj)
{
logDebug("PluginInstance fromStatic");
PluginInstance *i = new PluginInstance;
i->_loader = 0;
i->_instance = obj;
i->_ownInstance = false;
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
return i;
}
static PluginInstance *fromInstance(QObject *obj)
{
logDebug("PluginInstance fromInstance");
PluginInstance *i = new PluginInstance;
i->_loader = 0;
i->_instance = obj;
i->_ownInstance = true;
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
return i;
}
~PluginInstance()
{
QString str;
if(_instance)
str = _instance->metaObject()->className();
if(_ownInstance)
delete _instance;
if(_loader)
{
_loader->unload();
delete _loader;
}
logDebug(QString("PluginInstance deleted [%1]").arg(str));
}
void claim()
{
if(_loader)
_loader->moveToThread(0);
if(_ownInstance)
_instance->moveToThread(0);
}
QObject *instance()
{
return _instance;
}
bool sameType(const PluginInstance *other)
{
if(!_instance || !other->_instance)
return false;
if(qstrcmp(_instance->metaObject()->className(), other->_instance->metaObject()->className()) != 0)
return false;
return true;
}
};
class ProviderItem
{
public:
@ -35,61 +145,63 @@ public:
static ProviderItem *load(const QString &fname)
{
//printf("trying to load [%s]\n", qPrintable(fname));
QPluginLoader *lib = new QPluginLoader(fname);
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(lib->instance());
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
PluginInstance *i = PluginInstance::fromFile(fname);
if(!i)
return 0;
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(i->instance());
if(!plugin)
{
delete plugin;
delete lib;
logDebug("not a QCAPlugin or wrong interface");
delete i;
return 0;
}
//printf("success\n");
Provider *p = plugin->createProvider();
if(!p)
{
delete plugin;
delete lib;
logDebug("unable to create provider");
delete i;
return 0;
}
ProviderItem *i = new ProviderItem(lib, plugin, p);
i->fname = fname;
return i;
ProviderItem *pi = new ProviderItem(i, p);
pi->fname = fname;
return pi;
}
static ProviderItem *loadStatic(QObject *instance)
{
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(instance);
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
PluginInstance *i = PluginInstance::fromStatic(instance);
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(i->instance());
if(!plugin)
{
delete plugin;
logDebug("not a QCAPlugin or wrong interface");
delete i;
return 0;
}
Provider *p = plugin->createProvider();
if(!p)
{
delete plugin;
logDebug("unable to create provider");
delete i;
return 0;
}
ProviderItem *i = new ProviderItem(0, plugin, p);
return i;
ProviderItem *pi = new ProviderItem(i, p);
return pi;
}
static ProviderItem *fromClass(Provider *p)
{
ProviderItem *i = new ProviderItem(0, 0, p);
return i;
ProviderItem *pi = new ProviderItem(0, p);
return pi;
}
~ProviderItem()
{
delete p;
delete qcaPlugin;
delete lib;
delete instance;
}
void ensureInit()
@ -101,34 +213,33 @@ public:
}
private:
QPluginLoader *lib;
QCAPlugin *qcaPlugin;
PluginInstance *instance;
bool init_done;
ProviderItem(QPluginLoader *_lib, QCAPlugin *_qcaPlugin, Provider *_p)
ProviderItem(PluginInstance *_instance, Provider *_p)
{
lib = _lib;
qcaPlugin = _qcaPlugin;
instance = _instance;
p = _p;
init_done = false;
// disassociate from threads
if(qcaPlugin)
qcaPlugin->moveToThread(0);
if(lib)
lib->moveToThread(0);
instance->claim();
logDebug(QString("ProviderItem created: [%1]").arg(p->name()));
}
};
ProviderManager::ProviderManager()
{
g_pluginman = this;
def = 0;
scanned_static = false;
}
ProviderManager::~ProviderManager()
{
unloadAll();
delete def;
g_pluginman = 0;
}
void ProviderManager::scan()
@ -146,6 +257,7 @@ void ProviderManager::scan()
if(i->p && haveAlready(i->p->name()))
{
logDebug("skipping, we already have it");
delete i;
continue;
}
@ -157,8 +269,11 @@ void ProviderManager::scan()
// check plugin files
QStringList dirs = QCoreApplication::libraryPaths();
if(dirs.isEmpty())
logDebug("no Qt plugin paths");
for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
{
logDebug(QString("checking in path: [%1]").arg(*it));
QDir libpath(*it);
QDir dir(libpath.filePath(PLUGIN_SUBDIR));
if(!dir.exists())
@ -172,6 +287,13 @@ void ProviderManager::scan()
continue;
QString fname = fi.filePath();
logDebug(QString("checking file: [%1]").arg(fname));
if(!QLibrary::isLibrary(fname))
{
logDebug("skipping, not a library\n");
continue;
}
// make sure we haven't loaded this file before
bool haveFile = false;
for(int n = 0; n < providerItemList.count(); ++n)
@ -184,7 +306,10 @@ void ProviderManager::scan()
}
}
if(haveFile)
{
logDebug("skipping, we already loaded this file");
continue;
}
ProviderItem *i = ProviderItem::load(fname);
if(!i)
@ -192,6 +317,7 @@ void ProviderManager::scan()
if(i->p && haveAlready(i->p->name()))
{
logDebug("skipping, we already have it");
delete i;
continue;
}
@ -203,8 +329,12 @@ void ProviderManager::scan()
bool ProviderManager::add(Provider *p, int priority)
{
logDebug(QString("adding pre-made provider: [%1]").arg(p->name()));
if(haveAlready(p->name()))
{
logDebug("skipping, we already have it");
return false;
}
ProviderItem *i = ProviderItem::fromClass(p);
addItem(i, priority);
@ -366,6 +496,21 @@ const ProviderList & ProviderManager::providers() const
return providerList;
}
QString ProviderManager::diagnosticText() const
{
return dtext;
}
void ProviderManager::appendDiagnosticText(const QString &str)
{
dtext += str;
}
void ProviderManager::clearDiagnosticText()
{
dtext = QString();
}
void ProviderManager::addItem(ProviderItem *item, int priority)
{
if(priority < 0)
@ -397,6 +542,8 @@ void ProviderManager::addItem(ProviderItem *item, int priority)
providerItemList.insert(n, item);
providerList.insert(n, item->p);
}
logDebug(QString("item added [%1]").arg(item->p->name()));
}
bool ProviderManager::haveAlready(const QString &name) const

@ -51,7 +51,12 @@ namespace QCA
static void mergeFeatures(QStringList *a, const QStringList &b);
QString diagnosticText() const;
void appendDiagnosticText(const QString &str);
void clearDiagnosticText();
private:
QString dtext;
QList<ProviderItem*> providerItemList;
ProviderList providerList;
Provider *def;

@ -531,7 +531,7 @@ static QString getKeyStore(const QString &name)
int n = findByString(getKeyStoreStrings(storeList), name);
if(n != -1)
return storeList[n];
return 0;
return QString();
}
static QCA::KeyStoreEntry getKeyStoreEntry(QCA::KeyStore *store, const QString &name)
@ -668,6 +668,7 @@ static void usage()
printf("usage: qcatool [--command] (options)\n");
printf("commands:\n");
printf(" --help\n");
printf(" --plugins [-d]\n");
printf("\n");
printf(" --genrsa [bits] (passphrase)\n");
printf(" --gendsa [512|768|1024] (passphrase)\n");
@ -782,6 +783,64 @@ int main(int argc, char **argv)
return 1;
}
if(args[0] == "--plugins")
{
printf("Qt Library Paths:\n");
QStringList paths = QCoreApplication::libraryPaths();
if(!paths.isEmpty())
{
for(int n = 0; n < paths.count(); ++n)
{
printf(" %s\n", qPrintable(paths[n]));
}
}
else
printf(" (none)\n");
QCA::scanForPlugins();
QCA::ProviderList list = QCA::providers();
bool debug = false;
for(int n = 1; n < args.count(); ++n)
{
if(args[n] == "-d")
{
debug = true;
break;
}
}
if(debug)
{
QString str = QCA::pluginDiagnosticText();
QCA::clearPluginDiagnosticText();
QStringList lines = str.split('\n', QString::SkipEmptyParts);
for(int n = 0; n < lines.count(); ++n)
printf("qca: %s\n", qPrintable(lines[n]));
}
printf("Available Providers:\n");
if(!list.isEmpty())
{
for(int n = 0; n < list.count(); ++n)
{
printf(" %s\n", qPrintable(list[n]->name()));
}
}
else
printf(" (none)\n");
QCA::unloadAllPlugins();
if(debug)
{
QString str = QCA::pluginDiagnosticText();
QCA::clearPluginDiagnosticText();
QStringList lines = str.split('\n', QString::SkipEmptyParts);
for(int n = 0; n < lines.count(); ++n)
printf("qca: %s\n", qPrintable(lines[n]));
}
return 0;
}
// activate the KeyStoreManager and block until ready
QCA::keyStoreManager()->start();
QCA::keyStoreManager()->waitForBusyFinished();
@ -1232,7 +1291,7 @@ int main(int argc, char **argv)
//info[QCA::URI] = "http://psi.affinix.com/";
//info[QCA::DNS] = "psi.affinix.com";
//info[QCA::IPAddress] = "192.168.0.1";
//info[QCA::XMPP] = "justin@andbit.net";
//info.insert(QCA::XMPP, "justin@andbit.net");
opts.setInfo(info);
if(do_ca)