qgpgmerefreshkeysjob.cpp
1/*
2 qgpgmerefreshkeysjob.cpp
3
4 This file is part of libkleopatra, the KDE keymanagement library
5 Copyright (c) 2004 Klarälvdalens Datakonsult AB
6
7 Libkleopatra is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 Libkleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the TQt library by Trolltech AS, Norway (or with modified versions
24 of TQt that use the same license as TQt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 TQt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "qgpgmerefreshkeysjob.h"
38
39#include "gnupgprocessbase.h"
40#include "qgpgmeprogresstokenmapper.h"
41
42#include <kdebug.h>
43
44#include <gpgmepp/context.h>
45
46#include <qgpgme/eventloopinteractor.h>
47
48#include <tqstringlist.h>
49
50#include <gpg-error.h>
51
52#include <assert.h>
53
54Kleo::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob()
55 : RefreshKeysJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMERefreshKeysJob" ),
56 mProcess( 0 ),
57 mError( 0 )
58{
59
60}
61
62Kleo::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob() {
63
64}
65
66GpgME::Error Kleo::QGpgMERefreshKeysJob::start( const TQStringList & patterns ) {
67 assert( mPatternsToDo.empty() );
68
69 mPatternsToDo = patterns;
70 if ( mPatternsToDo.empty() )
71 mPatternsToDo.push_back( " " ); // empty list means all -> mae
72 // sure to fail the first
73 // startAProcess() guard clause
74
75 return startAProcess();
76}
77
78#if MAX_CMD_LENGTH < 65 + 128
79#error MAX_CMD_LENGTH is too low
80#endif
81
82GpgME::Error Kleo::QGpgMERefreshKeysJob::startAProcess() {
83 if ( mPatternsToDo.empty() )
84 return 0;
85 // create and start gpgsm process:
86 mProcess = new GnuPGProcessBase( this, "gpgsm -k --with-validation --force-crl-refresh --enable-crl-checks" );
87
88 // FIXME: obbtain the path to gpgsm from gpgme, so we use the same instance.
89 *mProcess << "gpgsm" << "-k" << "--with-validation" << "--force-crl-refresh"
90 << "--enable-crl-checks";
91 unsigned int commandLineLength = MAX_CMD_LENGTH;
92 commandLineLength -=
93 strlen("gpgsm") + 1 + strlen("-k") + 1 +
94 strlen("--with-validation") + 1 + strlen("--force-crl-refresh") + 1 +
95 strlen("--enable-crl-checks") + 1;
96 while ( !mPatternsToDo.empty() ) {
97 const TQCString pat = mPatternsToDo.front().utf8().stripWhiteSpace();
98 const unsigned int patLength = pat.length();
99 if ( patLength >= commandLineLength )
100 break;
101 mPatternsToDo.pop_front();
102 if ( pat.isEmpty() )
103 continue;
104 *mProcess << pat;
105 commandLineLength -= patLength + 1;
106 }
107
108 mProcess->setUsetStatusFD( true );
109
110 connect( mProcess, TQ_SIGNAL(processExited(TDEProcess*)),
111 TQ_SLOT(slotProcessExited(TDEProcess*)) );
112 connect( mProcess, TQ_SIGNAL(receivedStderr(TDEProcess*,char*,int)),
113 TQ_SLOT(slotStderr(TDEProcess*,char*,int)) );
114 connect( mProcess, TQ_SIGNAL(status(Kleo::GnuPGProcessBase*,const TQString&,const TQStringList&)),
115 TQ_SLOT(slotStatus(Kleo::GnuPGProcessBase*,const TQString&,const TQStringList&)) );
116
117 if ( !mProcess->start( TDEProcess::NotifyOnExit, TDEProcess::Stderr ) ) {
118 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else?
119 deleteLater();
120 return mError;
121 } else
122 return 0;
123}
124
125void Kleo::QGpgMERefreshKeysJob::slotCancel() {
126 if ( mProcess )
127 mProcess->kill();
128 mProcess = 0;
129 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
130}
131
132void Kleo::QGpgMERefreshKeysJob::slotStatus( GnuPGProcessBase * proc, const TQString & type, const TQStringList & args ) {
133 if ( proc != mProcess )
134 return;
135 TQStringList::const_iterator it = args.begin();
136 bool ok = false;
137
138 if ( type == "ERROR" ) {
139
140
141 if ( args.size() < 2 ) {
142 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
143 return;
144 }
145 const int source = (*++it).toInt( &ok );
146 if ( !ok ) {
147 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
148 return;
149 }
150 ok = false;
151 const int code = (*++it).toInt( &ok );
152 if ( !ok ) {
153 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
154 return;
155 }
156 mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
157
158
159 } else if ( type == "PROGRESS" ) {
160
161
162 if ( args.size() < 4 ) {
163 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
164 return;
165 }
166 const TQString what = *++it;
167 ++it; // don't use "type"...
168 const int cur = (*++it).toInt( &ok );
169 if ( !ok ) {
170 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"cur\", got something else" << endl;
171 return;
172 }
173 ok = false;
174 const int total = (*++it).toInt( &ok );
175 if ( !ok ) {
176 kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"total\", got something else" << endl;
177 return;
178 }
179 emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
180
181
182 }
183}
184
185void Kleo::QGpgMERefreshKeysJob::slotStderr( TDEProcess *, char *, int ) {
186 // implement? or not?
187}
188
189void Kleo::QGpgMERefreshKeysJob::slotProcessExited( TDEProcess * proc ) {
190 if ( proc != mProcess )
191 return;
192
193 if ( !mError && !mPatternsToDo.empty() ) {
194 if ( const GpgME::Error err = startAProcess() ) {
195 mError = err;
196 }
197 else {
198 return;
199 }
200 }
201
202 emit done();
203 if ( !mError &&
204 ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
205 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
206 emit result( mError );
207 deleteLater();
208}
209
210#include "qgpgmerefreshkeysjob.moc"
a base class for GPG and GPGSM processes.