chiasmusjob.cpp
00001 /* 00002 chiasmusjob.cpp 00003 00004 This file is part of libkleopatra, the KDE keymanagement library 00005 Copyright (c) 2005 Klarälvdalens Datakonsult AB 00006 00007 Libkleopatra is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License as 00009 published by the Free Software Foundation; either version 2 of the 00010 License, or (at your option) any later version. 00011 00012 Libkleopatra is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 00021 In addition, as a special exception, the copyright holders give 00022 permission to link the code of this program with any edition of 00023 the TQt library by Trolltech AS, Norway (or with modified versions 00024 of TQt that use the same license as TQt), and distribute linked 00025 combinations including the two. You must obey the GNU General 00026 Public License in all respects for all of the code used other than 00027 TQt. If you modify this file, you may extend this exception to 00028 your version of the file, but you are not obligated to do so. If 00029 you do not wish to do so, delete this exception statement from 00030 your version. 00031 */ 00032 00033 #ifdef HAVE_CONFIG_H 00034 #include <config.h> 00035 #endif 00036 00037 #include "chiasmusjob.h" 00038 #include "chiasmusbackend.h" 00039 #include "symcryptrunprocessbase.h" 00040 00041 #include "kleo/cryptoconfig.h" 00042 #include "ui/passphrasedialog.h" 00043 00044 #include <gpg-error.h> 00045 00046 #include <kshell.h> 00047 #include <klocale.h> 00048 #include <kdebug.h> 00049 #include <kmessagebox.h> 00050 00051 #include <tqtimer.h> 00052 #include <tqfileinfo.h> 00053 #include <tqvariant.h> 00054 00055 #include <memory> 00056 00057 #include <cassert> 00058 00059 Kleo::ChiasmusJob::ChiasmusJob( Mode mode ) 00060 : Kleo::SpecialJob( 0, 0 ), 00061 mSymCryptRun( 0 ), 00062 mError( 0 ), 00063 mCanceled( false ), 00064 mTimeout( false ), 00065 mMode( mode ) 00066 { 00067 00068 } 00069 00070 Kleo::ChiasmusJob::~ChiasmusJob() {} 00071 00072 GpgME::Error Kleo::ChiasmusJob::setup() { 00073 if ( !checkPreconditions() ) 00074 return mError = gpg_error( GPG_ERR_INV_VALUE ); 00075 00076 const Kleo::CryptoConfigEntry * class_ 00077 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "symcryptrun-class" ); 00078 const Kleo::CryptoConfigEntry * chiasmus 00079 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "path" ); 00080 const Kleo::CryptoConfigEntry * timeoutEntry 00081 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "timeout" ); 00082 if ( !class_ || !chiasmus || !timeoutEntry ) 00083 return mError = gpg_error( GPG_ERR_INTERNAL ); 00084 00085 mSymCryptRun = new SymCryptRunProcessBase( class_->stringValue(), 00086 KShell::tildeExpand( chiasmus->urlValue().path() ), 00087 mKey, mOptions, 00088 mMode == Encrypt 00089 ? SymCryptRunProcessBase::Encrypt 00090 : SymCryptRunProcessBase::Decrypt, 00091 this, "symcryptrun" ); 00092 TQTimer::singleShot( timeoutEntry->uintValue() * 1000, this, 00093 TQT_SLOT( slotTimeout() ) ); 00094 return 0; 00095 } 00096 00097 namespace { 00098 struct LaterDeleter { 00099 TQObject * _this; 00100 LaterDeleter( TQObject * o ) : _this( o ) {} 00101 ~LaterDeleter() { if ( _this ) _this->deleteLater(); } 00102 void disable() { _this = 0; } 00103 }; 00104 } 00105 00106 GpgME::Error Kleo::ChiasmusJob::start() { 00107 00108 LaterDeleter d( this ); 00109 00110 if ( const GpgME::Error err = setup() ) 00111 return mError = err; 00112 00113 connect( mSymCryptRun, TQT_SIGNAL(processExited(KProcess*)), 00114 this, TQT_SLOT(slotProcessExited(KProcess*)) ); 00115 00116 if ( !mSymCryptRun->launch( mInput ) ) 00117 return mError = gpg_error( GPG_ERR_ENOENT ); // what else? 00118 00119 d.disable(); 00120 return mError = 0; 00121 } 00122 00123 GpgME::Error Kleo::ChiasmusJob::slotProcessExited( KProcess * proc ) { 00124 if ( proc != mSymCryptRun ) 00125 mError = gpg_error( GPG_ERR_INTERNAL ); 00126 else if ( mCanceled ) 00127 mError = gpg_error( GPG_ERR_CANCELED ); 00128 else if ( mTimeout ) 00129 mError = gpg_error( GPG_ERR_TIMEOUT ); 00130 else if ( !proc->normalExit() ) 00131 mError = gpg_error( GPG_ERR_GENERAL ); 00132 else 00133 switch ( proc->exitStatus() ) { 00134 case 0: // success 00135 mOutput = mSymCryptRun->output(); 00136 mError = 0; 00137 break; 00138 default: 00139 case 1: // Some error occured 00140 mStderr = mSymCryptRun->stdErr(); 00141 mError = gpg_error( GPG_ERR_GENERAL ); 00142 break; 00143 case 2: // No valid passphrase was provided 00144 mError = gpg_error( GPG_ERR_INV_PASSPHRASE ); 00145 break; 00146 case 3: // Canceled 00147 mError = gpg_error( GPG_ERR_CANCELED ); 00148 break; 00149 } 00150 00151 const Kleo::CryptoConfigEntry * showOutput 00152 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "show-output" ); 00153 if ( showOutput && showOutput->boolValue() ) { 00154 showChiasmusOutput(); 00155 } 00156 00157 emit done(); 00158 emit SpecialJob::result( mError, TQVariant( mOutput ) ); 00159 return mError; 00160 } 00161 00162 void Kleo::ChiasmusJob::showChiasmusOutput() { 00163 kdDebug() << k_funcinfo << endl; 00164 if ( mStderr.isEmpty() ) 00165 return; 00166 KMessageBox::information( 0 /*how to get a parent widget?*/, 00167 mStderr, 00168 i18n( "Output from chiasmus" ) ); 00169 } 00170 00171 GpgME::Error Kleo::ChiasmusJob::exec() { 00172 if ( const GpgME::Error err = setup() ) 00173 return mError = err; 00174 00175 if ( !mSymCryptRun->launch( mInput, KProcess::Block ) ) { 00176 delete mSymCryptRun; mSymCryptRun = 0; 00177 return mError = gpg_error( GPG_ERR_ENOENT ); // what else? 00178 } 00179 00180 const GpgME::Error err = slotProcessExited( mSymCryptRun ); 00181 delete mSymCryptRun; mSymCryptRun = 0; 00182 return err; 00183 } 00184 00185 bool Kleo::ChiasmusJob::checkPreconditions() const { 00186 return !mKey.isEmpty(); 00187 } 00188 00189 void Kleo::ChiasmusJob::slotCancel() { 00190 if ( mSymCryptRun ) 00191 mSymCryptRun->kill(); 00192 mCanceled = true; 00193 } 00194 00195 void Kleo::ChiasmusJob::slotTimeout() { 00196 if ( !mSymCryptRun ) 00197 return; 00198 mSymCryptRun->kill(); 00199 mTimeout = true; 00200 } 00201 00202 00203 void Kleo::ChiasmusJob::showErrorDialog( TQWidget * parent, const TQString & caption ) const { 00204 if ( !mError ) 00205 return; 00206 if ( mError.isCanceled() ) 00207 return; 00208 const TQString msg = ( mMode == Encrypt 00209 ? i18n( "Encryption failed: %1" ) 00210 : i18n( "Decryption failed: %1" ) ) 00211 .arg( TQString::fromLocal8Bit( mError.asString() ) ); 00212 if ( !mStderr.isEmpty() ) { 00213 const TQString details = i18n( "The following was received on stderr:\n%1" ).arg( mStderr ); 00214 KMessageBox::detailedError( parent, msg, details, caption ); 00215 } else { 00216 KMessageBox::error( parent, msg, caption ); 00217 } 00218 } 00219 00220 #include "chiasmusjob.moc"