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 "qgpgmesecretkeyexportjob.h"
00038
00039 #include "gnupgprocessbase.h"
00040 #include "qgpgmeprogresstokenmapper.h"
00041
00042 #include <kdebug.h>
00043
00044 #include <gpgmepp/context.h>
00045 #include <gpgmepp/data.h>
00046
00047 #include <qgpgme/eventloopinteractor.h>
00048
00049 #include <qstringlist.h>
00050
00051 #include <gpg-error.h>
00052
00053 #include <string.h>
00054 #include <assert.h>
00055
00056 Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour )
00057 : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ),
00058 mProcess( 0 ),
00059 mError( 0 ),
00060 mArmour( armour )
00061 {
00062
00063 }
00064
00065 Kleo::QGpgMESecretKeyExportJob::~QGpgMESecretKeyExportJob() {
00066
00067 }
00068
00069 GpgME::Error Kleo::QGpgMESecretKeyExportJob::start( const QStringList & patterns ) {
00070 assert( mKeyData.isEmpty() );
00071
00072 if ( patterns.size() != 1 || patterns.front().isEmpty() )
00073 return mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_INV_VALUE );
00074
00075
00076 mProcess = new GnuPGProcessBase( this, "gpgsm --export-secret-key-p12" );
00077
00078
00079 *mProcess << "gpgsm" << "--export-secret-key-p12";
00080 if ( mArmour )
00081 *mProcess << "--armor";
00082 *mProcess << patterns.front().utf8();
00083
00084 mProcess->setUseStatusFD( true );
00085
00086 connect( mProcess, SIGNAL(processExited(KProcess*)),
00087 SLOT(slotProcessExited(KProcess*)) );
00088 connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)),
00089 SLOT(slotStdout(KProcess*,char*,int)) );
00090 connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)),
00091 SLOT(slotStderr(KProcess*,char*,int)) );
00092 connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)),
00093 SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) );
00094
00095 if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) {
00096 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT );
00097 deleteLater();
00098 return mError;
00099 } else
00100 return 0;
00101 }
00102
00103 void Kleo::QGpgMESecretKeyExportJob::slotCancel() {
00104 if ( mProcess )
00105 mProcess->kill();
00106 mProcess = 0;
00107 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
00108 }
00109
00110 void Kleo::QGpgMESecretKeyExportJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) {
00111 if ( proc != mProcess )
00112 return;
00113 QStringList::const_iterator it = args.begin();
00114 bool ok = false;
00115
00116 if ( type == "ERROR" ) {
00117
00118
00119 if ( args.size() < 2 ) {
00120 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
00121 return;
00122 }
00123 const int source = (*++it).toInt( &ok );
00124 if ( !ok ) {
00125 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
00126 return;
00127 }
00128 ok = false;
00129 const int code = (*++it).toInt( &ok );
00130 if ( !ok ) {
00131 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
00132 return;
00133 }
00134 mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
00135
00136
00137 } else if ( type == "PROGRESS" ) {
00138
00139
00140 if ( args.size() < 4 ) {
00141 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
00142 return;
00143 }
00144 const QString what = *++it;
00145 ++it;
00146 const int cur = (*++it).toInt( &ok );
00147 if ( !ok ) {
00148 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"cur\", got something else" << endl;
00149 return;
00150 }
00151 ok = false;
00152 const int total = (*++it).toInt( &ok );
00153 if ( !ok ) {
00154 kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"total\", got something else" << endl;
00155 return;
00156 }
00157 emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
00158
00159
00160 }
00161 }
00162
00163 void Kleo::QGpgMESecretKeyExportJob::slotStdout( KProcess * proc, char * buf, int buflen ) {
00164 if ( proc != mProcess )
00165 return;
00166 if ( buflen <= 0 )
00167 return;
00168 if ( !buf )
00169 return;
00170 const unsigned int oldlen = mKeyData.size();
00171 mKeyData.resize( oldlen + buflen );
00172 memcpy( mKeyData.data() + oldlen, buf, buflen );
00173 }
00174
00175 void Kleo::QGpgMESecretKeyExportJob::slotStderr( KProcess *, char *, int ) {
00176
00177 }
00178
00179 void Kleo::QGpgMESecretKeyExportJob::slotProcessExited( KProcess * proc ) {
00180 if ( proc != mProcess )
00181 return;
00182
00183 emit done();
00184 if ( !mError &&
00185 ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
00186 mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
00187 emit result( mError, mKeyData );
00188 deleteLater();
00189 }
00190
00191 #include "qgpgmesecretkeyexportjob.moc"