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 "hierarchicalkeylistjob.h"
00038 #include "cryptobackend.h"
00039 #include "keylistjob.h"
00040
00041 #include <klocale.h>
00042
00043 #include <qstringlist.h>
00044 #include <qtl.h>
00045
00046 #include <gpgmepp/key.h>
00047 #include <gpgmepp/context.h>
00048 #include <gpgmepp/data.h>
00049
00050 #include <gpg-error.h>
00051
00052 #include <iterator>
00053 #include <algorithm>
00054
00055 #include <assert.h>
00056
00057 Kleo::HierarchicalKeyListJob::HierarchicalKeyListJob( const CryptoBackend::Protocol * protocol,
00058 bool remote, bool includeSigs, bool validating )
00059 : KeyListJob( 0, "Kleo::HierarchicalKeyListJob" ),
00060 mProtocol( protocol ),
00061 mRemote( remote ),
00062 mIncludeSigs( includeSigs ),
00063 mValidating( validating ),
00064 mTruncated( false ),
00065 mIntermediateResult(),
00066 mJob( 0 )
00067 {
00068 assert( protocol );
00069 }
00070
00071 Kleo::HierarchicalKeyListJob::~HierarchicalKeyListJob() {
00072
00073 }
00074
00075 GpgME::Error Kleo::HierarchicalKeyListJob::start( const QStringList & patterns, bool secretOnly ) {
00076 if ( secretOnly || patterns.empty() )
00077 return gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION );
00078 qCopy( patterns.begin(), patterns.end(),
00079 std::inserter( mNextSet, mNextSet.begin() ) );
00080 const GpgME::Error err = startAJob();
00081 if ( err )
00082 deleteLater();
00083 return err;
00084 }
00085
00086 GpgME::KeyListResult Kleo::HierarchicalKeyListJob::exec( const QStringList &, bool,
00087 std::vector<GpgME::Key> & keys ) {
00088 keys.clear();
00089 return GpgME::KeyListResult( gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION ) );
00090 }
00091
00092 void Kleo::HierarchicalKeyListJob::slotNextKey( const GpgME::Key & key ) {
00093 if ( const char * chain_id = key.chainID() )
00094 mNextSet.insert( chain_id );
00095 if ( const char * fpr = key.primaryFingerprint() )
00096 if ( mSentSet.find( fpr ) == mSentSet.end() ) {
00097 mSentSet.insert( fpr );
00098 emit nextKey( key );
00099 }
00100 }
00101
00102 void Kleo::HierarchicalKeyListJob::slotCancel() {
00103 if ( mJob ) mJob->slotCancel();
00104 mNextSet.clear();
00105 }
00106
00107 void Kleo::HierarchicalKeyListJob::slotResult( const GpgME::KeyListResult & res ) {
00108 mJob = 0;
00109 mIntermediateResult.mergeWith( res );
00110 std::set<QString> tmp;
00111 std::set_difference( mNextSet.begin(), mNextSet.end(),
00112 mScheduledSet.begin(), mScheduledSet.end(),
00113 std::inserter( tmp, tmp.begin() ) );
00114 mNextSet.clear();
00115 std::set_difference( tmp.begin(), tmp.end(),
00116 mSentSet.begin(), mSentSet.end(),
00117 std::inserter( mNextSet, mNextSet.begin() ) );
00118 if ( mIntermediateResult.error() || mNextSet.empty() ) {
00119 emit done();
00120 emit result( mIntermediateResult );
00121 deleteLater();
00122 return;
00123 }
00124 if ( const GpgME::Error error = startAJob() ) {
00125 mIntermediateResult.mergeWith( GpgME::KeyListResult( error ) );
00126 emit done();
00127 emit result( mIntermediateResult );
00128 deleteLater();
00129 return;
00130 }
00131 #if 0 // FIXME
00132 const int current = mIt - mKeys.begin();
00133 const int total = mKeys.size();
00134 emit progress( i18n("progress info: \"%1 of %2\"","%1/%2").arg( current ).arg( total ), current, total );
00135 #endif
00136 }
00137
00138 GpgME::Error Kleo::HierarchicalKeyListJob::startAJob() {
00139 if ( mNextSet.empty() )
00140 return 0;
00141 mJob = mProtocol->keyListJob( mRemote, mIncludeSigs, mValidating );
00142 assert( mJob );
00143
00144
00145 connect( mJob, SIGNAL(nextKey(const GpgME::Key&)), SLOT(slotNextKey(const GpgME::Key&)) );
00146 connect( mJob, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotResult(const GpgME::KeyListResult&)) );
00147
00148 QStringList patterns;
00149 for ( std::set<QString>::const_iterator it = mNextSet.begin() ; it != mNextSet.end() ; ++it )
00150 patterns.push_back( *it );
00151
00152 mScheduledSet.insert( mNextSet.begin(), mNextSet.end() );
00153 mNextSet.clear();
00154
00155 return mJob->start( patterns, false );
00156 }
00157
00158 #include "hierarchicalkeylistjob.moc"