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"