33 #include <config-kleopatra.h>
39 #include <gpgme++/global.h>
40 #include <gpgme++/engineinfo.h>
41 #include <gpgme++/error.h>
43 #include <gpg-error.h>
51 #include <boost/shared_ptr.hpp>
52 #include <boost/range.hpp>
58 using namespace Kleo::_detail;
59 using namespace GpgME;
60 using namespace boost;
63 static const char * engines[] = {
64 "gpg",
"gpgsm",
"gpgconf"
66 return QString::fromLatin1( engines[eng] );
70 static const char * names[] = {
71 I18N_NOOP2(
"@title",
"GPG (OpenPGP Backend) installation" ),
72 I18N_NOOP2(
"@title",
"GpgSM (S/MIME Backend) installation" ),
73 I18N_NOOP2(
"@title",
"GpgConf (Configuration) installation" ),
75 return i18nc(
"@title", names[eng] );
82 explicit EngineCheck( GpgME::Engine eng )
88 void runTest( GpgME::Engine eng ) {
89 const Error err = GpgME::checkEngine( eng );
90 assert( !err.code() || err.code() == GPG_ERR_INV_ENGINE );
97 m_explaination = i18nc(
"@info",
98 "<para>A problem was detected with the <application>%1</application> backend.</para>",
101 const EngineInfo ei = engineInfo( eng );
103 m_error = i18n(
"not supported");
104 m_explaination += i18nc(
"@info",
105 "<para>It seems that the <icode>gpgme</icode> library was compiled without "
106 "support for this backend.</para>");
107 m_proposedFix += i18nc(
"@info",
108 "<para>Replace the <icode>gpgme</icode> library with a version compiled "
109 "with <application>%1</application> support.</para>",
111 }
else if ( ei.fileName() && !ei.version() ) {
112 m_error = i18n(
"not properly installed");
113 m_explaination += i18nc(
"@info",
114 "<para>Backend <command>%1</command> is not installed properly.</para>", QFile::decodeName( ei.fileName() ) );
115 m_proposedFix += i18nc(
"@info",
116 "<para>Please check the output of <command>%1 --version</command> manually.</para>",
117 QFile::decodeName( ei.fileName() ) );
118 }
else if ( ei.fileName() && ei.version() && ei.requiredVersion() ) {
119 m_error = i18n(
"too old");
120 m_explaination += i18nc(
"@info",
121 "<para>Backend <command>%1</command> is installed in version %2, "
122 "but at least version %3 is required.</para>",
123 QFile::decodeName( ei.fileName() ),
124 QString::fromUtf8( ei.version() ),
125 QString::fromUtf8( ei.requiredVersion() ) );
126 m_proposedFix += i18nc(
"@info",
127 "<para>Install <application>%1</application> version %2 or higher.</para>",
128 engine_name( eng ), QString::fromUtf8( ei.requiredVersion() ) );
130 m_error = m_explaination = i18n(
"unknown problem");
131 m_proposedFix += i18nc(
"@info",
132 "<para>Make sure <application>%1</application> is installed and "
133 "in <envar>PATH</envar>.</para>",
157 static bool is_version(
const char * actual,
int major,
int minor,
int patch ) {
158 QRegExp rx( QLatin1String(
"(\\d+)\\.(\\d+)\\.(\\d+)(?:-svn\\d+)?.*") );
159 if ( !rx.exactMatch( QString::fromUtf8( actual ) ) ) {
160 kDebug() <<
"Can't parse version " << actual;
164 int actual_version[3];
165 for (
int i = 0 ; i < 3 ; ++i ) {
167 actual_version[i] = rx.cap( i+1 ).toUInt( &ok );
171 kDebug() <<
"Parsed" << actual <<
"as: "
172 << actual_version[0] <<
'.'
173 << actual_version[1] <<
'.'
174 << actual_version[2] <<
'.' ;
176 const int required_version[] = { major, minor, patch };
179 ok = !std::lexicographical_compare( begin( actual_version ), end( actual_version ),
180 begin( required_version ), end( required_version ) );
181 kDebug( ok ) << QString::fromLatin1(
"%1.%2.%3" ).arg( major ).arg( minor ).arg( patch ) <<
"<=" << actual ;
182 kDebug( !ok ) << QString::fromLatin1(
"%1.%2.%3" ).arg( major ).arg( minor ).arg( patch ) <<
">" << actual ;
187 const Error err = GpgME::checkEngine( engine );
188 assert( !err || err.code() == GPG_ERR_INV_ENGINE );
190 const EngineInfo ei = GpgME::engineInfo( engine );
192 m_skipped = err || !
is_version( ei.version(), major, minor, patch );
197 if ( !err && ei.version() ) {
199 m_explaination = i18nc(
"@info",
200 "<para><application>%1</application> v%2.%3.%4 is required for this test, but only %5 is installed.</para>",
201 engine_name( engine ), major, minor, patch, QString::fromUtf8( ei.version() ) );
202 m_proposedFix += i18nc(
"@info",
203 "<para>Install <application>%1</application> version %2 or higher.</para>",
204 engine_name( engine ), QString::fromLatin1(
"%1.%2.%3" ).arg( major ).arg( minor ).arg( patch ) );
207 m_explaination = i18nc(
"@info",
208 "<para><application>%1</application> is required for this test, but does not seem available.</para>"
209 "<para>See tests further up for more information.</para>",
211 m_proposedFix = i18nc(
"@info %1: test name",
212 "<para>See \"%1\" above.</para>",
test_name( engine ) );
static bool is_version(const char *actual, int major, int minor, int patch)
boost::shared_ptr< SelfTest > makeGpgSmEngineCheckSelfTest()
bool ensureEngineVersion(GpgME::Engine, int major, int minor, int patch)
static QString test_name(GpgME::Engine eng)
boost::shared_ptr< SelfTest > makeGpgConfEngineCheckSelfTest()
static QString engine_name(GpgME::Engine eng)
boost::shared_ptr< SelfTest > makeGpgEngineCheckSelfTest()