33 #include <config-kleopatra.h>
44 #include <kleo/exception.h>
52 #include <QApplication>
62 using namespace boost;
66 class Process :
public QProcess {
68 explicit Process( QObject * parent=0 )
69 : QProcess( parent ) {}
70 void close() { closeReadChannel( StandardOutput ); }
76 class InputImplBase :
public Input {
78 InputImplBase() :
Input(), m_customLabel(), m_defaultLabel() {}
80 QString label()
const {
return m_customLabel.isEmpty() ? m_defaultLabel : m_customLabel; }
81 void setDefaultLabel(
const QString & l ) { m_defaultLabel = l; }
82 void setLabel(
const QString & l ) { m_customLabel = l; }
83 QString errorString()
const {
84 if ( m_errorString.dirty() )
85 m_errorString = doErrorString();
90 virtual QString doErrorString()
const {
94 return i18n(
"No input device");
98 QString m_customLabel;
99 QString m_defaultLabel;
105 class PipeInput :
public InputImplBase {
110 unsigned int classification()
const;
111 unsigned long long size()
const {
return 0; }
117 class ProcessStdOutInput :
public InputImplBase {
119 explicit ProcessStdOutInput(
const QString & cmd,
const QStringList & args,
const QDir & wd,
const QByteArray & stdin_=QByteArray() );
122 unsigned int classification()
const {
return 0U; }
123 unsigned long long size()
const {
return 0; }
124 QString label()
const;
127 QString doErrorString()
const;
130 const QString m_command;
131 const QStringList m_arguments;
135 class FileInput :
public InputImplBase {
137 explicit FileInput(
const QString & fileName );
140 QString label()
const {
141 return m_io ? QFileInfo( m_fileName ).fileName() : InputImplBase::label();
144 unsigned int classification()
const;
145 unsigned long long size()
const {
return QFileInfo( m_fileName ).size(); }
152 #ifndef QT_NO_CLIPBOARD
153 class ClipboardInput :
public Input {
155 explicit ClipboardInput( QClipboard::Mode mode );
157 void setLabel(
const QString & label );
158 QString label()
const;
160 unsigned int classification()
const;
161 unsigned long long size()
const {
return m_buffer ? m_buffer->buffer().size() : 0; }
162 QString errorString()
const {
return QString(); }
165 const QClipboard::Mode m_mode;
168 #endif // QT_NO_CLIPBOARD
175 po->setDefaultLabel( label );
185 if ( !kdp->open( fd, QIODevice::ReadOnly ) )
186 throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
187 i18n(
"Could not open FD %1 for reading",
193 unsigned int PipeInput::classification()
const {
207 FileInput::FileInput(
const QString & fileName )
209 m_io(), m_fileName( fileName )
214 if ( !file->open( QIODevice::ReadOnly ) )
215 throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
216 i18n(
"Could not open file \"%1\" for reading", fileName ) );
223 m_io(), m_fileName( file->fileName() )
227 if ( file->isOpen() && !file->isReadable() )
228 throw Exception( gpg_error( GPG_ERR_INV_ARG ),
229 i18n(
"File \"%1\" is already open, but not for reading", file->fileName() ) );
230 if ( !file->isOpen() && !file->open( QIODevice::ReadOnly ) )
231 throw Exception( errno ? gpg_error_from_errno( errno ) : gpg_error( GPG_ERR_EIO ),
232 i18n(
"Could not open file \"%1\" for reading", m_fileName ) );
236 unsigned int FileInput::classification()
const {
242 return shared_ptr<Input>(
new ProcessStdOutInput( command, QStringList(), QDir::current() ) );
246 return shared_ptr<Input>(
new ProcessStdOutInput( command, args, QDir::current() ) );
254 return shared_ptr<Input>(
new ProcessStdOutInput( command, QStringList(), QDir::current(), stdin_ ) );
258 return shared_ptr<Input>(
new ProcessStdOutInput( command, args, QDir::current(), stdin_ ) );
267 const QByteArray & data;
268 explicit Outputter(
const QByteArray & data ) : data( data ) {}
270 static QDebug
operator<<( QDebug s,
const Outputter & o ) {
271 if (
const quint64 size = o.data.size() )
272 s <<
" << (" << size <<
"bytes)";
277 ProcessStdOutInput::ProcessStdOutInput(
const QString & cmd,
const QStringList & args,
const QDir & wd,
const QByteArray & stdin_ )
281 m_proc( new Process )
283 const QIODevice::OpenMode openMode =
284 stdin_.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite ;
285 kDebug() <<
"cd" << wd.absolutePath() << endl << cmd << args << Outputter( stdin_ );
287 throw Exception( gpg_error( GPG_ERR_INV_ARG ),
288 i18n(
"Command not specified") );
289 m_proc->setWorkingDirectory( wd.absolutePath() );
290 m_proc->start( cmd, args, openMode );
291 if ( !m_proc->waitForStarted() )
292 throw Exception( gpg_error( GPG_ERR_EIO ),
293 i18n(
"Could not start %1 process: %2", cmd, m_proc->errorString() ) );
295 if ( !stdin_.isEmpty() ) {
296 if ( m_proc->write( stdin_ ) != stdin_.size() )
297 throw Exception( gpg_error( GPG_ERR_EIO ),
298 i18n(
"Failed to write input to %1 process: %2", cmd, m_proc->errorString() ) );
299 m_proc->closeWriteChannel();
303 QString ProcessStdOutInput::label()
const {
305 return InputImplBase::label();
307 const QString cmdline = ( QStringList( m_command ) + m_arguments.mid(0,3) ).join( QLatin1String(
" ") );
308 if ( m_arguments.size() > 3 )
309 return i18nc(
"e.g. \"Output of tar xf - file1 ...\"",
"Output of %1 ...", cmdline );
311 return i18nc(
"e.g. \"Output of tar xf - file\"",
"Output of %1", cmdline );
314 QString ProcessStdOutInput::doErrorString()
const {
316 if ( m_proc->exitStatus() == QProcess::NormalExit && m_proc->exitCode() == 0 )
318 if ( m_proc->error() == QProcess::UnknownError )
319 return i18n(
"Error while running %1:\n%2", m_command,
320 QString::fromLocal8Bit( m_proc->readAllStandardError().trimmed().constData() ) );
322 return i18n(
"Failed to execute %1: %2", m_command, m_proc->errorString() );
325 #ifndef QT_NO_CLIPBOARD
333 if ( QClipboard *
const cb = QApplication::clipboard() )
334 return cb->text().toUtf8();
339 ClipboardInput::ClipboardInput( QClipboard::Mode mode )
342 m_buffer( new QBuffer )
345 if ( !m_buffer->open( QIODevice::ReadOnly ) )
346 throw Exception( gpg_error( GPG_ERR_EIO ),
347 i18n(
"Could not open clipboard for reading" ) );
350 void ClipboardInput::setLabel(
const QString & ) {
354 QString ClipboardInput::label()
const {
356 case QClipboard::Clipboard:
357 return i18n(
"Clipboard contents" );
358 case QClipboard::FindBuffer:
359 return i18n(
"FindBuffer contents" );
360 case QClipboard::Selection:
361 return i18n(
"Current selection" );
366 unsigned int ClipboardInput::classification()
const {
369 #endif // QT_NO_CLIPBOARD
static qulonglong assuanFD2int(assuan_fd_t fd)
#define kleo_assert(cond)
unsigned int classify(const QString &filename)
static boost::shared_ptr< const Log > instance()
unsigned int classifyContent(const QByteArray &data)