LCOV - code coverage report
Current view: top level - lang/qt/src - qgpgmenewcryptoconfig.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 94 310 30.3 %
Date: 2017-03-02 17:11:10 Functions: 25 68 36.8 %

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

Generated by: LCOV version 1.13