LCOV - code coverage report
Current view: top level - lang/qt/src - qgpgmenewcryptoconfig.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 97 309 31.4 %
Date: 2018-11-15 08:49:49 Functions: 26 68 38.2 %

          Line data    Source code
       1             : /*
       2             :     qgpgmenewcryptoconfig.cpp
       3             : 
       4             :     This file is part of qgpgme, the Qt API binding for gpgme
       5             :     Copyright (c) 2010 Klarälvdalens Datakonsult AB
       6             :     Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
       7             :     Software engineering by Intevation GmbH
       8             : 
       9             :     QGpgME is free software; you can redistribute it and/or
      10             :     modify it under the terms of the GNU General Public License as
      11             :     published by the Free Software Foundation; either version 2 of the
      12             :     License, or (at your option) any later version.
      13             : 
      14             :     QGpgME is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :     General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program; if not, write to the Free Software
      21             :     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      22             : 
      23             :     In addition, as a special exception, the copyright holders give
      24             :     permission to link the code of this program with any edition of
      25             :     the Qt library by Trolltech AS, Norway (or with modified versions
      26             :     of Qt that use the same license as Qt), and distribute linked
      27             :     combinations including the two.  You must obey the GNU General
      28             :     Public License in all respects for all of the code used other than
      29             :     Qt.  If you modify this file, you may extend this exception to
      30             :     your version of the file, but you are not obligated to do so.  If
      31             :     you do not wish to do so, delete this exception statement from
      32             :     your version.
      33             : */
      34             : 
      35             : #ifdef HAVE_CONFIG_H
      36             :  #include "config.h"
      37             : #endif
      38             : 
      39             : #include "qgpgmenewcryptoconfig.h"
      40             : 
      41             : #include <QDebug>
      42             : #include "gpgme_backend_debug.h"
      43             : 
      44             : #include <QFile>
      45             : #include <QDir>
      46             : 
      47             : #include "global.h"
      48             : #include "error.h"
      49             : 
      50             : 
      51             : #include <sstream>
      52             : #include <string>
      53             : #include <functional>
      54             : #include <cassert>
      55             : #include <functional>
      56             : 
      57             : using namespace QGpgME;
      58             : using namespace GpgME;
      59             : using namespace GpgME::Configuration;
      60             : 
      61             : namespace
      62             : {
      63             : struct Select1St {
      64             :     template <typename U, typename V>
      65             :     const U &operator()(const std::pair<U, V> &p) const
      66             :     {
      67             :         return p.first;
      68             :     }
      69             :     template <typename U, typename V>
      70             :     const U &operator()(const QPair<U, V> &p) const
      71             :     {
      72             :         return p.first;
      73             :     }
      74             : };
      75             : }
      76             : 
      77             : // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
      78             : // have 2 threads talking to gpgconf anyway? :)
      79             : static bool s_duringClear = false;
      80             : 
      81           1 : QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
      82           1 :     :  m_parsed(false)
      83             : {
      84           1 : }
      85             : 
      86           0 : QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
      87             : {
      88           0 :     clear();
      89           0 : }
      90             : 
      91          23 : void QGpgMENewCryptoConfig::reloadConfiguration(bool)
      92             : {
      93          23 :     clear();
      94             : 
      95          46 :     Error error;
      96          46 :     const std::vector<Component> components = Component::load(error);
      97             : #ifndef NDEBUG
      98             :     {
      99          46 :         std::stringstream ss;
     100          23 :         ss << "error: " << error
     101          23 :            << "components:\n";
     102             :         std::copy(components.begin(), components.end(),
     103          23 :                   std::ostream_iterator<Component>(ss, "\n"));
     104          23 :         qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
     105             :     }
     106             : #endif
     107             : #if 0
     108             :     TODO port?
     109             :     if (error && showErrors) {
     110             :         const QString wmsg = i18n("<qt>Failed to execute gpgconf:<p>%1</p></qt>", QString::fromLocal8Bit(error.asString()));
     111             :         qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
     112             :         KMessageBox::error(0, wmsg);
     113             :     }
     114             : #endif
     115         161 :     Q_FOREACH(const Component & c, components) {
     116         276 :         const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
     117         138 :         comp->setComponent(c);
     118         138 :         m_componentsByName[ comp->name() ] = comp;
     119             :     }
     120          23 :     m_parsed = true;
     121          23 : }
     122             : 
     123           0 : QStringList QGpgMENewCryptoConfig::componentList() const
     124             : {
     125           0 :     if (!m_parsed) {
     126           0 :         const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
     127             :     }
     128           0 :     QStringList result;
     129             :     std::transform(m_componentsByName.begin(), m_componentsByName.end(),
     130             :                    std::back_inserter(result),
     131           0 :                    mem_fn(&QGpgMENewCryptoConfigComponent::name));
     132           0 :     return result;
     133             : }
     134             : 
     135          33 : QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
     136             : {
     137          33 :     if (!m_parsed) {
     138          23 :         const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
     139             :     }
     140          33 :     return m_componentsByName.value(name).get();
     141             : }
     142             : 
     143          22 : void QGpgMENewCryptoConfig::sync(bool runtime)
     144             : {
     145         154 :     Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
     146         132 :     c->sync(runtime);
     147          22 : }
     148             : 
     149          45 : void QGpgMENewCryptoConfig::clear()
     150             : {
     151          45 :     s_duringClear = true;
     152          45 :     m_componentsByName.clear();
     153          45 :     s_duringClear = false;
     154          45 :     m_parsed = false; // next call to componentList/component will need to run gpgconf again
     155          45 : }
     156             : 
     157             : ////
     158             : 
     159         138 : QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
     160             :     : CryptoConfigComponent(),
     161         138 :       m_component()
     162             : {
     163             : 
     164         138 : }
     165             : 
     166         138 : void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
     167             : {
     168         138 :     m_component = component;
     169         138 :     m_groupsByName.clear();
     170             : 
     171         276 :     std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
     172             : 
     173         276 :     const std::vector<Option> options = m_component.options();
     174        3082 :     Q_FOREACH(const Option & o, options)
     175        2944 :     if (o.flags() & Group) {
     176         621 :         if (group) {
     177         506 :             m_groupsByName[group->name()] = group;
     178             :         }
     179         621 :         group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
     180        2323 :     } else if (group) {
     181        4646 :         const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
     182        4646 :         const QString name = entry->name();
     183        2323 :         group->m_entryNames.push_back(name);
     184        2323 :         group->m_entriesByName[name] = entry;
     185             :     } else {
     186           0 :         qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
     187             :     }
     188         138 :     if (group) {
     189         115 :         m_groupsByName[group->name()] = group;
     190             :     }
     191             : 
     192         138 : }
     193             : 
     194         264 : QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
     195             : 
     196         138 : QString QGpgMENewCryptoConfigComponent::name() const
     197             : {
     198         138 :     return QString::fromUtf8(m_component.name());
     199             : }
     200             : 
     201           0 : QString QGpgMENewCryptoConfigComponent::description() const
     202             : {
     203           0 :     return QString::fromUtf8(m_component.description());
     204             : }
     205             : 
     206           0 : QStringList QGpgMENewCryptoConfigComponent::groupList() const
     207             : {
     208           0 :     QStringList result;
     209           0 :     result.reserve(m_groupsByName.size());
     210             :     std::transform(m_groupsByName.begin(), m_groupsByName.end(),
     211             :                    std::back_inserter(result),
     212           0 :                    std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
     213           0 :     return result;
     214             : }
     215             : 
     216          33 : QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
     217             : {
     218          33 :     return m_groupsByName.value(name).get();
     219             : }
     220             : 
     221         132 : void QGpgMENewCryptoConfigComponent::sync(bool runtime)
     222             : {
     223             :     Q_UNUSED(runtime) // runtime is always set by engine_gpgconf
     224         264 :     if (const Error err = m_component.save()) {
     225           0 :         qCWarning(GPGPME_BACKEND_LOG) << ":"
     226           0 :             << "Error from gpgconf while saving configuration: %1"
     227           0 :             << QString::fromLocal8Bit(err.asString());
     228             :     }
     229         132 : }
     230             : 
     231             : ////
     232             : 
     233         621 : QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
     234             :     : CryptoConfigGroup(),
     235             :       m_component(comp),
     236         621 :       m_option(option)
     237             : {
     238         621 : }
     239             : 
     240        1188 : QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
     241             : 
     242         621 : QString QGpgMENewCryptoConfigGroup::name() const
     243             : {
     244         621 :     return QString::fromUtf8(m_option.name());
     245             : }
     246             : 
     247           0 : QString QGpgMENewCryptoConfigGroup::description() const
     248             : {
     249           0 :     return QString::fromUtf8(m_option.description());
     250             : }
     251             : 
     252           0 : QString QGpgMENewCryptoConfigGroup::path() const
     253             : {
     254           0 :     if (const std::shared_ptr<QGpgMENewCryptoConfigComponent> c = m_component.lock()) {
     255           0 :         return c->name() + QLatin1Char('/') + name();
     256             :     } else {
     257           0 :         return QString();
     258             :     }
     259             : }
     260             : 
     261           0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigGroup::level() const
     262             : {
     263             :     // two casts to make SunCC happy:
     264           0 :     return static_cast<CryptoConfigEntry::Level>(static_cast<unsigned int>(m_option.level()));
     265             : }
     266             : 
     267           0 : QStringList QGpgMENewCryptoConfigGroup::entryList() const
     268             : {
     269           0 :     return m_entryNames;
     270             : }
     271             : 
     272          33 : QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
     273             : {
     274          33 :     return m_entriesByName.value(name).get();
     275             : }
     276             : 
     277           0 : static QString urlpart_encode(const QString &str)
     278             : {
     279           0 :     QString enc(str);
     280           0 :     enc.replace(QLatin1Char('%'), QStringLiteral("%25"));   // first!
     281           0 :     enc.replace(QLatin1Char(':'), QStringLiteral("%3a"));
     282             :     //qCDebug(GPGPME_BACKEND_LOG) <<"  urlpart_encode:" << str <<" ->" << enc;
     283           0 :     return enc;
     284             : }
     285             : 
     286           0 : static QString urlpart_decode(const QString &str)
     287             : {
     288           0 :     return QUrl::fromPercentEncoding(str.toLatin1());
     289             : }
     290             : 
     291             : // gpgconf arg type number -> NewCryptoConfigEntry arg type enum mapping
     292           0 : static QGpgME::CryptoConfigEntry::ArgType knownArgType(int argType, bool &ok)
     293             : {
     294           0 :     ok = true;
     295           0 :     switch (argType) {
     296             :     case 0: // none
     297           0 :         return QGpgME::CryptoConfigEntry::ArgType_None;
     298             :     case 1: // string
     299           0 :         return QGpgME::CryptoConfigEntry::ArgType_String;
     300             :     case 2: // int32
     301           0 :         return QGpgME::CryptoConfigEntry::ArgType_Int;
     302             :     case 3: // uint32
     303           0 :         return QGpgME::CryptoConfigEntry::ArgType_UInt;
     304             :     case 32: // pathname
     305           0 :         return QGpgME::CryptoConfigEntry::ArgType_Path;
     306             :     case 33: // ldap server
     307           0 :         return QGpgME::CryptoConfigEntry::ArgType_LDAPURL;
     308             :     default:
     309           0 :         ok = false;
     310           0 :         return QGpgME::CryptoConfigEntry::ArgType_None;
     311             :     }
     312             : }
     313             : 
     314        2323 : QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
     315        2323 :     : m_group(group), m_option(option)
     316             : {
     317        2323 : }
     318             : 
     319             : #if 0
     320             : QVariant QGpgMENewCryptoConfigEntry::stringToValue(const QString &str, bool unescape) const
     321             : {
     322             :     const bool isString = isStringType();
     323             : 
     324             :     if (isList()) {
     325             :         if (argType() == ArgType_None) {
     326             :             bool ok = true;
     327             :             const QVariant v = str.isEmpty() ? 0U : str.toUInt(&ok);
     328             :             if (!ok) {
     329             :                 qCWarning(GPGPME_BACKEND_LOG) << "list-of-none should have an unsigned int as value:" << str;
     330             :             }
     331             :             return v;
     332             :         }
     333             :         QList<QVariant> lst;
     334             :         QStringList items = str.split(',', QString::SkipEmptyParts);
     335             :         for (QStringList::const_iterator valit = items.constBegin(); valit != items.constEnd(); ++valit) {
     336             :             QString val = *valit;
     337             :             if (isString) {
     338             :                 if (val.isEmpty()) {
     339             :                     lst << QVariant(QString());
     340             :                     continue;
     341             :                 } else if (unescape) {
     342             :                     if (val[0] != '"') { // see README.gpgconf
     343             :                         qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
     344             :                     }
     345             :                     val = val.mid(1);
     346             :                 }
     347             :             }
     348             :             lst << QVariant(unescape ? gpgconf_unescape(val) : val);
     349             :         }
     350             :         return lst;
     351             :     } else { // not a list
     352             :         QString val(str);
     353             :         if (isString) {
     354             :             if (val.isEmpty()) {
     355             :                 return QVariant(QString());    // not set  [ok with lists too?]
     356             :             } else if (unescape) {
     357             :                 if (val[0] != '"') { // see README.gpgconf
     358             :                     qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
     359             :                 }
     360             :                 val = val.mid(1);
     361             :             }
     362             :         }
     363             :         return QVariant(unescape ? gpgconf_unescape(val) : val);
     364             :     }
     365             : }
     366             : #endif
     367             : 
     368        6666 : QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
     369             : {
     370             : #ifndef NDEBUG
     371        2222 :     if (!s_duringClear && m_option.dirty())
     372           0 :         qCWarning(GPGPME_BACKEND_LOG) << "Deleting a QGpgMENewCryptoConfigEntry that was modified (" << m_option.description() << ")"
     373           0 :                                       << "You forgot to call sync() (to commit) or clear() (to discard)";
     374             : #endif
     375        4444 : }
     376             : 
     377        2323 : QString QGpgMENewCryptoConfigEntry::name() const
     378             : {
     379        2323 :     return QString::fromUtf8(m_option.name());
     380             : }
     381             : 
     382           0 : QString QGpgMENewCryptoConfigEntry::description() const
     383             : {
     384           0 :     return QString::fromUtf8(m_option.description());
     385             : }
     386             : 
     387           0 : QString QGpgMENewCryptoConfigEntry::path() const
     388             : {
     389           0 :     if (const std::shared_ptr<QGpgMENewCryptoConfigGroup> g = m_group.lock()) {
     390           0 :         return g->path() + QLatin1Char('/') + name();
     391             :     } else {
     392           0 :         return QString();
     393             :     }
     394             : }
     395             : 
     396          10 : bool QGpgMENewCryptoConfigEntry::isOptional() const
     397             : {
     398          10 :     return m_option.flags() & Optional;
     399             : }
     400             : 
     401           0 : bool QGpgMENewCryptoConfigEntry::isReadOnly() const
     402             : {
     403           0 :     return m_option.flags() & NoChange;
     404             : }
     405             : 
     406          43 : bool QGpgMENewCryptoConfigEntry::isList() const
     407             : {
     408          43 :     return m_option.flags() & List;
     409             : }
     410             : 
     411           0 : bool QGpgMENewCryptoConfigEntry::isRuntime() const
     412             : {
     413           0 :     return m_option.flags() & Runtime;
     414             : }
     415             : 
     416           0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigEntry::level() const
     417             : {
     418             :     // two casts to make SunCC happy:
     419           0 :     return static_cast<Level>(static_cast<unsigned int>(m_option.level()));
     420             : }
     421             : 
     422           0 : CryptoConfigEntry::ArgType QGpgMENewCryptoConfigEntry::argType() const
     423             : {
     424           0 :     bool ok = false;
     425           0 :     const ArgType type = knownArgType(m_option.type(), ok);
     426           0 :     if (ok) {
     427           0 :         return type;
     428             :     } else {
     429           0 :         return knownArgType(m_option.alternateType(), ok);
     430             :     }
     431             : }
     432             : 
     433           0 : bool QGpgMENewCryptoConfigEntry::isSet() const
     434             : {
     435           0 :     return m_option.set();
     436             : }
     437             : 
     438           0 : bool QGpgMENewCryptoConfigEntry::boolValue() const
     439             : {
     440           0 :     Q_ASSERT(m_option.alternateType() == NoType);
     441           0 :     Q_ASSERT(!isList());
     442           0 :     return m_option.currentValue().boolValue();
     443             : }
     444             : 
     445          22 : QString QGpgMENewCryptoConfigEntry::stringValue() const
     446             : {
     447             :     //return toString( false );
     448          22 :     Q_ASSERT(m_option.alternateType() == StringType);
     449          22 :     Q_ASSERT(!isList());
     450          22 :     return QString::fromUtf8(m_option.currentValue().stringValue());
     451             : }
     452             : 
     453           0 : int QGpgMENewCryptoConfigEntry::intValue() const
     454             : {
     455           0 :     Q_ASSERT(m_option.alternateType() == IntegerType);
     456           0 :     Q_ASSERT(!isList());
     457           0 :     return m_option.currentValue().intValue();
     458             : }
     459             : 
     460           0 : unsigned int QGpgMENewCryptoConfigEntry::uintValue() const
     461             : {
     462           0 :     Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
     463           0 :     Q_ASSERT(!isList());
     464           0 :     return m_option.currentValue().uintValue();
     465             : }
     466             : 
     467           0 : static QUrl parseURL(int mRealArgType, const QString &str)
     468             : {
     469           0 :     if (mRealArgType == 33) {   // LDAP server
     470             :         // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
     471           0 :         QStringList items = str.split(QLatin1Char(':'));
     472           0 :         if (items.count() == 5) {
     473           0 :             QStringList::const_iterator it = items.constBegin();
     474           0 :             QUrl url;
     475           0 :             url.setScheme(QStringLiteral("ldap"));
     476           0 :             url.setHost(urlpart_decode(*it++));
     477             : 
     478             :             bool ok;
     479           0 :             const int port = (*it++).toInt(&ok);
     480           0 :             if (ok) {
     481           0 :                 url.setPort(port);
     482           0 :             } else if (!it->isEmpty()) {
     483           0 :                 qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server port, ignoring: \"" << *it << "\"";
     484             :             }
     485             : 
     486           0 :             const QString userName = urlpart_decode(*it++);
     487           0 :             if (!userName.isEmpty()) {
     488           0 :                 url.setUserName(userName);
     489             :             }
     490           0 :             const QString passWord = urlpart_decode(*it++);
     491           0 :             if (!passWord.isEmpty()) {
     492           0 :                 url.setPassword(passWord);
     493             :             }
     494           0 :             url.setQuery(urlpart_decode(*it));
     495           0 :             return url;
     496             :         } else {
     497           0 :             qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server:" << str;
     498             :         }
     499             :     }
     500             :     // other URLs : assume wellformed URL syntax.
     501           0 :     return QUrl(str);
     502             : }
     503             : 
     504             : // The opposite of parseURL
     505           0 : static QString splitURL(int mRealArgType, const QUrl &url)
     506             : {
     507           0 :     if (mRealArgType == 33) {   // LDAP server
     508             :         // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
     509           0 :         Q_ASSERT(url.scheme() == QLatin1String("ldap"));
     510           0 :         return urlpart_encode(url.host()) + QLatin1Char(':') +
     511           0 :                (url.port() != -1 ? QString::number(url.port()) : QString()) + QLatin1Char(':') +     // -1 is used for default ports, omit
     512           0 :                urlpart_encode(url.userName()) + QLatin1Char(':') +
     513           0 :                urlpart_encode(url.password()) + QLatin1Char(':') +
     514           0 :                urlpart_encode(url.query());
     515             :     }
     516           0 :     return url.path();
     517             : }
     518             : 
     519           0 : QUrl QGpgMENewCryptoConfigEntry::urlValue() const
     520             : {
     521           0 :     const Type type = m_option.type();
     522           0 :     Q_ASSERT(type == FilenameType || type == LdapServerType);
     523           0 :     Q_ASSERT(!isList());
     524           0 :     if (type == FilenameType) {
     525           0 :         QUrl url = QUrl::fromLocalFile(m_option.currentValue().stringValue());
     526           0 :         return url;
     527             :     }
     528           0 :     return parseURL(type, stringValue());
     529             : }
     530             : 
     531           0 : unsigned int QGpgMENewCryptoConfigEntry::numberOfTimesSet() const
     532             : {
     533           0 :     Q_ASSERT(m_option.alternateType() == NoType);
     534           0 :     Q_ASSERT(isList());
     535           0 :     return m_option.currentValue().uintValue();
     536             : }
     537             : 
     538           0 : std::vector<int> QGpgMENewCryptoConfigEntry::intValueList() const
     539             : {
     540           0 :     Q_ASSERT(m_option.alternateType() == IntegerType);
     541           0 :     Q_ASSERT(isList());
     542           0 :     return m_option.currentValue().intValues();
     543             : }
     544             : 
     545           0 : std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
     546             : {
     547           0 :     Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
     548           0 :     Q_ASSERT(isList());
     549           0 :     return m_option.currentValue().uintValues();
     550             : }
     551             : 
     552           0 : QStringList QGpgMENewCryptoConfigEntry::stringValueList() const
     553             : {
     554           0 :     Q_ASSERT(isList());
     555           0 :     const Argument arg = m_option.currentValue();
     556           0 :     const std::vector<const char *> values = arg.stringValues();
     557           0 :     QStringList ret;
     558           0 :     for(const char *value: values) {
     559           0 :         ret << QString::fromUtf8(value);
     560             :     }
     561           0 :     return ret;
     562             : }
     563             : 
     564           0 : QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
     565             : {
     566           0 :     const Type type = m_option.type();
     567           0 :     Q_ASSERT(type == FilenameType || type == LdapServerType);
     568           0 :     Q_ASSERT(isList());
     569           0 :     const Argument arg = m_option.currentValue();
     570           0 :     const std::vector<const char *> values = arg.stringValues();
     571           0 :     QList<QUrl> ret;
     572           0 :     Q_FOREACH(const char *value, values)
     573           0 :     if (type == FilenameType) {
     574           0 :         QUrl url;
     575           0 :         url.setPath(QFile::decodeName(value));
     576           0 :         ret << url;
     577             :     } else {
     578           0 :         ret << parseURL(type, QString::fromUtf8(value));
     579             :     }
     580           0 :     return ret;
     581             : }
     582             : 
     583           1 : void QGpgMENewCryptoConfigEntry::resetToDefault()
     584             : {
     585           1 :     m_option.resetToDefaultValue();
     586           1 : }
     587             : 
     588           0 : void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
     589             : {
     590           0 :     Q_ASSERT(m_option.alternateType() == NoType);
     591           0 :     Q_ASSERT(!isList());
     592             :     // A "no arg" option is either set or not set.
     593             :     // Being set means createNoneArgument(), being unset means resetToDefault()
     594           0 :     m_option.setNewValue(m_option.createNoneArgument(b));
     595           0 : }
     596             : 
     597          21 : void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
     598             : {
     599          21 :     Q_ASSERT(m_option.alternateType() == StringType);
     600          21 :     Q_ASSERT(!isList());
     601          21 :     const Type type = m_option.type();
     602             :     // When setting a string to empty (and there's no default), we need to act like resetToDefault
     603             :     // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
     604             :     // "gpgconf: argument required for option ocsp-responder"
     605          21 :     if (str.isEmpty() && !isOptional()) {
     606          10 :         m_option.resetToDefaultValue();
     607          11 :     } else if (type == FilenameType) {
     608           0 :         m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
     609             :     } else {
     610          11 :         m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
     611             :     }
     612          21 : }
     613             : 
     614           0 : void QGpgMENewCryptoConfigEntry::setIntValue(int i)
     615             : {
     616           0 :     Q_ASSERT(m_option.alternateType() == IntegerType);
     617           0 :     Q_ASSERT(!isList());
     618           0 :     m_option.setNewValue(m_option.createIntArgument(i));
     619           0 : }
     620             : 
     621           0 : void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
     622             : {
     623           0 :     Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
     624           0 :     Q_ASSERT(!isList());
     625           0 :     m_option.setNewValue(m_option.createUIntArgument(i));
     626           0 : }
     627             : 
     628           0 : void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
     629             : {
     630           0 :     const Type type = m_option.type();
     631           0 :     Q_ASSERT(type == FilenameType || type == LdapServerType);
     632           0 :     Q_ASSERT(!isList());
     633           0 :     const QString str = splitURL(type, url);
     634             :     // cf. setStringValue()
     635           0 :     if (str.isEmpty() && !isOptional()) {
     636           0 :         m_option.resetToDefaultValue();
     637           0 :     } else if (type == FilenameType) {
     638           0 :         m_option.setNewValue(m_option.createStringArgument(QDir::toNativeSeparators(url.toLocalFile()).toUtf8().constData()));
     639             :     } else {
     640           0 :         m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
     641             :     }
     642           0 : }
     643             : 
     644           0 : void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
     645             : {
     646           0 :     Q_ASSERT(m_option.alternateType() == NoType);
     647           0 :     Q_ASSERT(isList());
     648           0 :     m_option.setNewValue(m_option.createNoneListArgument(i));
     649           0 : }
     650             : 
     651           0 : void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
     652             : {
     653           0 :     Q_ASSERT(m_option.alternateType() == IntegerType);
     654           0 :     Q_ASSERT(isList());
     655           0 :     m_option.setNewValue(m_option.createIntListArgument(lst));
     656           0 : }
     657             : 
     658           0 : void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
     659             : {
     660           0 :     Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
     661           0 :     Q_ASSERT(isList());
     662           0 :     m_option.setNewValue(m_option.createUIntListArgument(lst));
     663           0 : }
     664             : 
     665           0 : void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
     666             : {
     667           0 :     const Type type = m_option.type();
     668           0 :     Q_ASSERT(m_option.alternateType() == StringType);
     669           0 :     Q_ASSERT(isList());
     670           0 :     std::vector<std::string> values;
     671           0 :     values.reserve(urls.size());
     672           0 :     Q_FOREACH (const QUrl &url, urls)
     673           0 :         if (type == FilenameType) {
     674           0 :             values.push_back(QFile::encodeName(url.path()).constData());
     675             :         } else {
     676           0 :             values.push_back(splitURL(type, url).toUtf8().constData());
     677             :         }
     678           0 :     m_option.setNewValue(m_option.createStringListArgument(values));
     679           0 : }
     680             : 
     681           0 : bool QGpgMENewCryptoConfigEntry::isDirty() const
     682             : {
     683           0 :     return m_option.dirty();
     684             : }
     685             : 
     686             : #if 0
     687             : QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
     688             : {
     689             :     // Basically the opposite of stringToValue
     690             :     if (isStringType()) {
     691             :         if (mValue.isNull()) {
     692             :             return QString();
     693             :         } else if (isList()) { // string list
     694             :             QStringList lst = mValue.toStringList();
     695             :             if (escape) {
     696             :                 for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
     697             :                     if (!(*it).isNull()) {
     698             :                         *it = gpgconf_escape(*it).prepend("\"");
     699             :                     }
     700             :                 }
     701             :             }
     702             :             QString res = lst.join(",");
     703             :             //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
     704             :             return res;
     705             :         } else { // normal string
     706             :             QString res = mValue.toString();
     707             :             if (escape) {
     708             :                 res = gpgconf_escape(res).prepend("\"");
     709             :             }
     710             :             return res;
     711             :         }
     712             :     }
     713             :     if (!isList()) { // non-list non-string
     714             :         if (mArgType == ArgType_None) {
     715             :             return mValue.toBool() ? QString::fromLatin1("1") : QString();
     716             :         } else { // some int
     717             :             Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
     718             :             return mValue.toString(); // int to string conversion
     719             :         }
     720             :     }
     721             : 
     722             :     // Lists (of other types than strings)
     723             :     if (mArgType == ArgType_None) {
     724             :         return QString::number(numberOfTimesSet());
     725             :     }
     726             :     QStringList ret;
     727             :     QList<QVariant> lst = mValue.toList();
     728             :     for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
     729             :         ret << (*it).toString(); // QVariant does the conversion
     730             :     }
     731             :     return ret.join(",");
     732             : }
     733             : 
     734             : QString QGpgMENewCryptoConfigEntry::outputString() const
     735             : {
     736             :     Q_ASSERT(mSet);
     737             :     return toString(true);
     738             : }
     739             : 
     740             : bool QGpgMENewCryptoConfigEntry::isStringType() const
     741             : {
     742             :     return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
     743             :             || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
     744             :             || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
     745             :             || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
     746             : }
     747             : 
     748             : void QGpgMENewCryptoConfigEntry::setDirty(bool b)
     749             : {
     750             :     mDirty = b;
     751             : }
     752             : #endif

Generated by: LCOV version 1.13