Line data Source code
1 : /*
2 : qgpgmelistallkeysjob.cpp
3 :
4 : This file is part of qgpgme, the Qt API binding for gpgme
5 : Copyright (c) 2004,2008 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 "qgpgmelistallkeysjob.h"
39 :
40 : #include "key.h"
41 : #include "context.h"
42 : #include "keylistresult.h"
43 : #include <gpg-error.h>
44 :
45 : #include <algorithm>
46 :
47 : #include <cstdlib>
48 : #include <cstring>
49 : #include <cassert>
50 :
51 : using namespace QGpgME;
52 : using namespace GpgME;
53 :
54 0 : QGpgMEListAllKeysJob::QGpgMEListAllKeysJob(Context *context)
55 : : mixin_type(context),
56 0 : mResult()
57 : {
58 0 : lateInitialization();
59 0 : }
60 :
61 0 : QGpgMEListAllKeysJob::~QGpgMEListAllKeysJob() {}
62 :
63 0 : static KeyListResult do_list_keys(Context *ctx, std::vector<Key> &keys, bool secretOnly)
64 : {
65 :
66 0 : const char **pat = 0;
67 0 : if (const Error err = ctx->startKeyListing(pat, secretOnly)) {
68 0 : return KeyListResult(0, err);
69 0 : }
70 :
71 0 : Error err;
72 0 : do {
73 0 : keys.push_back(ctx->nextKey(err));
74 0 : } while (!err);
75 :
76 0 : keys.pop_back();
77 :
78 0 : const KeyListResult result = ctx->endKeyListing();
79 0 : ctx->cancelPendingOperation();
80 0 : return result;
81 : }
82 :
83 : namespace
84 : {
85 :
86 : template <typename ForwardIterator, typename BinaryPredicate>
87 0 : ForwardIterator unique_by_merge(ForwardIterator first, ForwardIterator last, BinaryPredicate pred)
88 : {
89 0 : first = std::adjacent_find(first, last, pred);
90 0 : if (first == last) {
91 0 : return last;
92 : }
93 :
94 0 : ForwardIterator dest = first;
95 0 : dest->mergeWith(*++first);
96 0 : while (++first != last)
97 0 : if (pred(*dest, *first)) {
98 0 : dest->mergeWith(*first);
99 : } else {
100 0 : *++dest = *first;
101 : }
102 0 : return ++dest;
103 : }
104 :
105 : }
106 :
107 0 : static void merge_keys(std::vector<Key> &merged, std::vector<Key> &pub, std::vector<Key> &sec)
108 : {
109 0 : merged.reserve(pub.size() + sec.size());
110 :
111 : std::merge(pub.begin(), pub.end(),
112 : sec.begin(), sec.end(),
113 : std::back_inserter(merged),
114 0 : ByFingerprint<std::less>());
115 :
116 0 : merged.erase(unique_by_merge(merged.begin(), merged.end(), ByFingerprint<std::equal_to>()),
117 0 : merged.end());
118 0 : }
119 :
120 0 : static QGpgMEListAllKeysJob::result_type list_keys(Context *ctx, bool mergeKeys)
121 : {
122 0 : std::vector<Key> pub, sec, merged;
123 0 : KeyListResult r;
124 :
125 0 : r.mergeWith(do_list_keys(ctx, pub, false));
126 0 : std::sort(pub.begin(), pub.end(), ByFingerprint<std::less>());
127 :
128 0 : r.mergeWith(do_list_keys(ctx, sec, true));
129 0 : std::sort(sec.begin(), sec.end(), ByFingerprint<std::less>());
130 :
131 0 : if (mergeKeys) {
132 0 : merge_keys(merged, pub, sec);
133 : } else {
134 0 : merged.swap(pub);
135 : }
136 0 : return std::make_tuple(r, merged, sec, QString(), Error());
137 : }
138 :
139 0 : Error QGpgMEListAllKeysJob::start(bool mergeKeys)
140 : {
141 0 : run(std::bind(&list_keys, std::placeholders::_1, mergeKeys));
142 0 : return Error();
143 : }
144 :
145 0 : KeyListResult QGpgMEListAllKeysJob::exec(std::vector<Key> &pub, std::vector<Key> &sec, bool mergeKeys)
146 : {
147 0 : const result_type r = list_keys(context(), mergeKeys);
148 0 : resultHook(r);
149 0 : pub = std::get<1>(r);
150 0 : sec = std::get<2>(r);
151 0 : return std::get<0>(r);
152 : }
153 :
154 0 : void QGpgMEListAllKeysJob::resultHook(const result_type &tuple)
155 : {
156 0 : mResult = std::get<0>(tuple);
157 0 : }
158 :
159 : #if 0
160 : void QGpgMEListAllKeysJob::showErrorDialog(QWidget *parent, const QString &caption) const
161 : {
162 : if (!mResult.error() || mResult.error().isCanceled()) {
163 : return;
164 : }
165 : const QString msg = i18n("<qt><p>An error occurred while fetching "
166 : "the keys from the backend:</p>"
167 : "<p><b>%1</b></p></qt>",
168 : QString::fromLocal8Bit(mResult.error().asString()));
169 : KMessageBox::error(parent, msg, caption);
170 : }
171 : #endif
172 : #include "qgpgmelistallkeysjob.moc"
|