00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
#ifdef HAVE_CONFIG_H
00034
#include <config.h>
00035
#endif
00036
00037
#include "qgpgmerefreshkeysjob.h"
00038
00039
#include "gnupgprocessbase.h"
00040
#include "qgpgmeprogresstokenmapper.h"
00041
00042
#include <kdebug.h>
00043
00044
#include <gpgmepp/context.h>
00045
00046
#include <qgpgme/eventloopinteractor.h>
00047
00048
#include <qstringlist.h>
00049
00050
#include <gpg-error.h>
00051
00052
#include <assert.h>
00053
00054 Kleo::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob()
00055 : RefreshKeysJob( QGpgME::EventLoopInteractor::instance(),
"Kleo::QGpgMERefreshKeysJob" ),
00056 mProcess( 0 ),
00057 mError( 0 )
00058 {
00059
00060 }
00061
00062 Kleo::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob() {
00063
00064 }
00065
00066 GpgME::Error Kleo::QGpgMERefreshKeysJob::start(
const QStringList & patterns ) {
00067 assert( mPatternsToDo.empty() );
00068
00069 mPatternsToDo = patterns;
00070
if ( mPatternsToDo.empty() )
00071 mPatternsToDo.push_back(
" " );
00072
00073
00074
00075
return startAProcess();
00076 }
00077
00078
#if MAX_CMD_LENGTH < 65 + 128
00079
#error MAX_CMD_LENGTH is too low
00080
#endif
00081
00082 GpgME::Error Kleo::QGpgMERefreshKeysJob::startAProcess() {
00083
if ( mPatternsToDo.empty() )
00084
return 0;
00085
00086 mProcess =
new GnuPGProcessBase(
this,
"gpgsm -k --with-validation --force-crl-refresh --enable-crl-checks" );
00087
00088
00089 *mProcess <<
"gpgsm" <<
"-k" <<
"--with-validation" <<
"--force-crl-refresh"
00090 <<
"--enable-crl-checks";
00091
unsigned int commandLineLength = MAX_CMD_LENGTH;
00092 commandLineLength -=
00093 strlen(
"gpgsm") + 1 + strlen(
"-k") + 1 +
00094 strlen(
"--with-validation") + 1 + strlen(
"--force-crl-refresh") + 1 +
00095 strlen(
"--enable-crl-checks") + 1;
00096
while ( !mPatternsToDo.empty() ) {
00097
const QCString pat = mPatternsToDo.front().utf8().stripWhiteSpace();
00098
const unsigned int patLength = pat.length();
00099
if ( patLength >= commandLineLength )
00100
break;
00101 mPatternsToDo.pop_front();
00102
if ( pat.isEmpty() )
00103
continue;
00104 *mProcess << pat;
00105 commandLineLength -= patLength + 1;
00106 }
00107
00108 mProcess->setUseStatusFD(
true );
00109
00110 connect( mProcess, SIGNAL(processExited(KProcess*)),
00111 SLOT(slotProcessExited(KProcess*)) );
00112 connect( mProcess, SIGNAL(receivedStderr(KProcess*,
char*,
int)),
00113 SLOT(slotStderr(KProcess*,
char*,
int)) );
00114 connect( mProcess, SIGNAL(status(
Kleo::GnuPGProcessBase*,
const QString&,
const QStringList&)),
00115 SLOT(slotStatus(
Kleo::GnuPGProcessBase*,
const QString&,
const QStringList&)) );
00116
00117
if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) {
00118 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT );
00119 deleteLater();
00120
return mError;
00121 }
else
00122
return 0;
00123 }
00124
00125
void Kleo::QGpgMERefreshKeysJob::slotCancel() {
00126
if ( mProcess )
00127 mProcess->kill();
00128 mProcess = 0;
00129 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
00130 }
00131
00132
void Kleo::QGpgMERefreshKeysJob::slotStatus( GnuPGProcessBase * proc,
const QString & type,
const QStringList & args ) {
00133
if ( proc != mProcess )
00134
return;
00135 QStringList::const_iterator it = args.begin();
00136
bool ok =
false;
00137
00138
if ( type ==
"ERROR" ) {
00139
00140
00141
if ( args.size() < 2 ) {
00142 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
00143
return;
00144 }
00145
const int source = (*++it).toInt( &ok );
00146
if ( !ok ) {
00147 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
00148
return;
00149 }
00150 ok =
false;
00151
const int code = (*++it).toInt( &ok );
00152
if ( !ok ) {
00153 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
00154
return;
00155 }
00156 mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
00157
00158
00159 }
else if ( type ==
"PROGRESS" ) {
00160
00161
00162
if ( args.size() < 4 ) {
00163 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
00164
return;
00165 }
00166
const QString what = *++it;
00167 ++it;
00168
const int cur = (*++it).toInt( &ok );
00169
if ( !ok ) {
00170 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"cur\", got something else" << endl;
00171
return;
00172 }
00173 ok =
false;
00174
const int total = (*++it).toInt( &ok );
00175
if ( !ok ) {
00176 kdDebug( 5150 ) <<
"Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"total\", got something else" << endl;
00177
return;
00178 }
00179 emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
00180
00181
00182 }
00183 }
00184
00185
void Kleo::QGpgMERefreshKeysJob::slotStderr( KProcess *,
char *,
int ) {
00186
00187 }
00188
00189
void Kleo::QGpgMERefreshKeysJob::slotProcessExited( KProcess * proc ) {
00190
if ( proc != mProcess )
00191
return;
00192
00193
if ( !mError && !mPatternsToDo.empty() )
00194
if (
const GpgME::Error err = startAProcess() )
00195 mError = err;
00196
else
00197
return;
00198
00199 emit done();
00200
if ( !mError &&
00201 ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
00202 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
00203 emit result( mError );
00204 deleteLater();
00205 }
00206
00207
#include "qgpgmerefreshkeysjob.moc"