• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • utils
input.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  utils/input.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007 Klarälvdalens Datakonsult AB
6 
7  Kleopatra is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  Kleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "input.h"
36 
37 #include "detail_p.h"
38 #include "classify.h"
39 #include "kdpipeiodevice.h"
40 #include "log.h"
41 #include "kleo_assert.h"
42 #include "cached.h"
43 
44 #include <kleo/exception.h>
45 
46 #include <KDebug>
47 #include <KLocale>
48 
49 #include <QFile>
50 #include <QString>
51 #include <QClipboard>
52 #include <QApplication>
53 #include <QByteArray>
54 #include <QBuffer>
55 #include <QDir>
56 #include <QFileInfo>
57 #include <QProcess>
58 
59 #include <errno.h>
60 
61 using namespace Kleo;
62 using namespace boost;
63 
64 namespace {
65 
66  class Process : public QProcess {
67  public:
68  explicit Process( QObject * parent=0 )
69  : QProcess( parent ) {}
70  /* reimp */ void close() { closeReadChannel( StandardOutput ); }
71  };
72 }
73 
74 namespace {
75 
76  class InputImplBase : public Input {
77  public:
78  InputImplBase() : Input(), m_customLabel(), m_defaultLabel() {}
79 
80  /* reimp */ QString label() const { return m_customLabel.isEmpty() ? m_defaultLabel : m_customLabel; }
81  void setDefaultLabel( const QString & l ) { m_defaultLabel = l; }
82  /* reimp */ void setLabel( const QString & l ) { m_customLabel = l; }
83  /* reimp */ QString errorString() const {
84  if ( m_errorString.dirty() )
85  m_errorString = doErrorString();
86  return m_errorString;
87  }
88 
89  private:
90  virtual QString doErrorString() const {
91  if ( const shared_ptr<QIODevice> io = ioDevice() )
92  return io->errorString();
93  else
94  return i18n("No input device");
95  }
96 
97  private:
98  QString m_customLabel;
99  QString m_defaultLabel;
100  mutable cached<QString> m_errorString;
101  };
102 
103 
104 
105  class PipeInput : public InputImplBase {
106  public:
107  explicit PipeInput( assuan_fd_t fd );
108 
109  /* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_io; }
110  /* reimp */ unsigned int classification() const;
111  /* reimp */ unsigned long long size() const { return 0; }
112 
113  private:
114  shared_ptr<QIODevice> m_io;
115  };
116 
117  class ProcessStdOutInput : public InputImplBase {
118  public:
119  explicit ProcessStdOutInput( const QString & cmd, const QStringList & args, const QDir & wd, const QByteArray & stdin_=QByteArray() );
120 
121  /* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_proc; }
122  /* reimp */ unsigned int classification() const { return 0U; } // plain text
123  /* reimp */ unsigned long long size() const { return 0; }
124  /* reimp */ QString label() const;
125 
126  private:
127  /* reimp */ QString doErrorString() const;
128 
129  private:
130  const QString m_command;
131  const QStringList m_arguments;
132  const shared_ptr<Process> m_proc;
133  };
134 
135  class FileInput : public InputImplBase {
136  public:
137  explicit FileInput( const QString & fileName );
138  explicit FileInput( const shared_ptr<QFile> & file );
139 
140  /* reimp */ QString label() const {
141  return m_io ? QFileInfo( m_fileName ).fileName() : InputImplBase::label();
142  }
143  /* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_io; }
144  /* reimp */ unsigned int classification() const;
145  /* reimp */ unsigned long long size() const { return QFileInfo( m_fileName ).size(); }
146 
147  private:
148  shared_ptr<QIODevice> m_io;
149  QString m_fileName;
150  };
151 
152 #ifndef QT_NO_CLIPBOARD
153  class ClipboardInput : public Input {
154  public:
155  explicit ClipboardInput( QClipboard::Mode mode );
156 
157  /* reimp */ void setLabel( const QString & label );
158  /* reimp */ QString label() const;
159  /* reimp */ shared_ptr<QIODevice> ioDevice() const { return m_buffer; }
160  /* reimp */ unsigned int classification() const;
161  /* reimp */ unsigned long long size() const { return m_buffer ? m_buffer->buffer().size() : 0; }
162  /* reimp */ QString errorString() const { return QString(); }
163 
164  private:
165  const QClipboard::Mode m_mode;
166  shared_ptr<QBuffer> m_buffer;
167  };
168 #endif // QT_NO_CLIPBOARD
169 
170 }
171 
172 
173 shared_ptr<Input> Input::createFromPipeDevice( assuan_fd_t fd, const QString & label ) {
174  shared_ptr<PipeInput> po( new PipeInput( fd ) );
175  po->setDefaultLabel( label );
176  return po;
177 }
178 
179 PipeInput::PipeInput( assuan_fd_t fd )
180  : InputImplBase(),
181  m_io()
182 {
183  shared_ptr<KDPipeIODevice> kdp( new KDPipeIODevice );
184  errno = 0;
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",
188  _detail::assuanFD2int( fd ) ) );
189  m_io = Log::instance()->createIOLogger( kdp, QLatin1String("pipe-input"), Log::Read );
190 }
191 
192 
193 unsigned int PipeInput::classification() const {
194  notImplemented();
195  return 0;
196 }
197 
198 
199 shared_ptr<Input> Input::createFromFile( const QString & fileName, bool ) {
200  return shared_ptr<Input>( new FileInput( fileName ) );
201 }
202 
203 shared_ptr<Input> Input::createFromFile( const shared_ptr<QFile> & file ) {
204  return shared_ptr<Input>( new FileInput( file ) );
205 }
206 
207 FileInput::FileInput( const QString & fileName )
208  : InputImplBase(),
209  m_io(), m_fileName( fileName )
210 {
211  shared_ptr<QFile> file( new QFile( fileName ) );
212 
213  errno = 0;
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 ) );
217  m_io = Log::instance()->createIOLogger( file, QLatin1String("file-in"), Log::Read );
218 
219 }
220 
221 FileInput::FileInput( const shared_ptr<QFile> & file )
222  : InputImplBase(),
223  m_io(), m_fileName( file->fileName() )
224 {
225  kleo_assert( file );
226  errno = 0;
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 ) );
233  m_io = Log::instance()->createIOLogger( file, QLatin1String("file-in"), Log::Read );
234 }
235 
236 unsigned int FileInput::classification() const {
237  return classify( m_fileName );
238 }
239 
240 
241 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command ) {
242  return shared_ptr<Input>( new ProcessStdOutInput( command, QStringList(), QDir::current() ) );
243 }
244 
245 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command, const QStringList & args ) {
246  return shared_ptr<Input>( new ProcessStdOutInput( command, args, QDir::current() ) );
247 }
248 
249 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command, const QStringList & args, const QDir & wd ) {
250  return shared_ptr<Input>( new ProcessStdOutInput( command, args, wd ) );
251 }
252 
253 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command, const QByteArray & stdin_ ) {
254  return shared_ptr<Input>( new ProcessStdOutInput( command, QStringList(), QDir::current(), stdin_ ) );
255 }
256 
257 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command, const QStringList & args, const QByteArray & stdin_ ) {
258  return shared_ptr<Input>( new ProcessStdOutInput( command, args, QDir::current(), stdin_ ) );
259 }
260 
261 shared_ptr<Input> Input::createFromProcessStdOut( const QString & command, const QStringList & args, const QDir & wd, const QByteArray & stdin_ ) {
262  return shared_ptr<Input>( new ProcessStdOutInput( command, args, wd, stdin_ ) );
263 }
264 
265 namespace {
266  struct Outputter {
267  const QByteArray & data;
268  explicit Outputter( const QByteArray & data ) : data( data ) {}
269  };
270  static QDebug operator<<( QDebug s, const Outputter & o ) {
271  if ( const quint64 size = o.data.size() )
272  s << " << (" << size << "bytes)";
273  return s;
274  }
275 }
276 
277 ProcessStdOutInput::ProcessStdOutInput( const QString & cmd, const QStringList & args, const QDir & wd, const QByteArray & stdin_ )
278  : InputImplBase(),
279  m_command( cmd ),
280  m_arguments( args ),
281  m_proc( new Process )
282 {
283  const QIODevice::OpenMode openMode =
284  stdin_.isEmpty() ? QIODevice::ReadOnly : QIODevice::ReadWrite ;
285  kDebug() << "cd" << wd.absolutePath() << endl << cmd << args << Outputter( stdin_ );
286  if ( cmd.isEmpty() )
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() ) );
294 
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();
300  }
301 }
302 
303 QString ProcessStdOutInput::label() const {
304  if ( !m_proc )
305  return InputImplBase::label();
306  // output max. 3 arguments
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 );
310  else
311  return i18nc( "e.g. \"Output of tar xf - file\"", "Output of %1", cmdline );
312 }
313 
314 QString ProcessStdOutInput::doErrorString() const {
315  kleo_assert( m_proc );
316  if ( m_proc->exitStatus() == QProcess::NormalExit && m_proc->exitCode() == 0 )
317  return QString();
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() ) );
321  else
322  return i18n( "Failed to execute %1: %2", m_command, m_proc->errorString() );
323 }
324 
325 #ifndef QT_NO_CLIPBOARD
326 shared_ptr<Input> Input::createFromClipboard() {
327  return shared_ptr<Input>( new ClipboardInput( QClipboard::Clipboard ) );
328 }
329 
330 static QByteArray dataFromClipboard( QClipboard::Mode mode )
331 {
332  Q_UNUSED( mode );
333  if ( QClipboard * const cb = QApplication::clipboard() )
334  return cb->text().toUtf8();
335  else
336  return QByteArray();
337 }
338 
339 ClipboardInput::ClipboardInput( QClipboard::Mode mode )
340  : Input(),
341  m_mode( mode ),
342  m_buffer( new QBuffer )
343 {
344  m_buffer->setData( dataFromClipboard( mode ) );
345  if ( !m_buffer->open( QIODevice::ReadOnly ) )
346  throw Exception( gpg_error( GPG_ERR_EIO ),
347  i18n( "Could not open clipboard for reading" ) );
348 }
349 
350 void ClipboardInput::setLabel( const QString & ) {
351  notImplemented();
352 }
353 
354 QString ClipboardInput::label() const {
355  switch ( m_mode ) {
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" );
362  };
363  return QString();
364 }
365 
366 unsigned int ClipboardInput::classification() const {
367  return classifyContent( m_buffer->data() );
368 }
369 #endif // QT_NO_CLIPBOARD
370 
371 Input::~Input() {}
372 
373 void Input::finalize() {
374  if ( const shared_ptr<QIODevice> io = ioDevice() )
375  if ( io->isOpen() )
376  io->close();
377 }
input.h
notImplemented
#define notImplemented()
Definition: kleo_assert.h:92
classify.h
dataFromClipboard
static QByteArray dataFromClipboard(QClipboard::Mode mode)
Definition: input.cpp:330
Kleo::Log::Read
Definition: log.h:54
kleo_assert.h
boost::shared_ptr< QIODevice >
cached.h
Kleo::Input::createFromClipboard
static boost::shared_ptr< Input > createFromClipboard()
Definition: input.cpp:326
KDPipeIODevice
Definition: kdpipeiodevice.h:29
operator<<
QDebug operator<<(QDebug debug, const std::vector< T, A > &v)
Definition: headerview.cpp:78
Kleo::Input::createFromFile
static boost::shared_ptr< Input > createFromFile(const QString &filename, bool dummy=false)
Definition: input.cpp:199
Kleo::_detail::assuanFD2int
static qulonglong assuanFD2int(assuan_fd_t fd)
Definition: detail_p.h:101
Kleo::Input::ioDevice
virtual boost::shared_ptr< QIODevice > ioDevice() const =0
kleo_assert
#define kleo_assert(cond)
Definition: kleo_assert.h:84
Kleo::cached
Definition: cached.h:41
Kleo::classify
unsigned int classify(const QString &filename)
Definition: classify.cpp:154
Kleo::Log::instance
static boost::shared_ptr< const Log > instance()
Definition: log.cpp:94
Kleo::Input::createFromPipeDevice
static boost::shared_ptr< Input > createFromPipeDevice(assuan_fd_t fd, const QString &label)
Definition: input.cpp:173
Kleo::Input::finalize
void finalize()
Definition: input.cpp:373
kdpipeiodevice.h
detail_p.h
assuan_fd_t
int assuan_fd_t
Definition: kleo-assuan.h:72
Kleo::Input::createFromProcessStdOut
static boost::shared_ptr< Input > createFromProcessStdOut(const QString &command)
Definition: input.cpp:241
Kleo::classifyContent
unsigned int classifyContent(const QByteArray &data)
Definition: classify.cpp:183
log.h
Kleo::Input::errorString
virtual QString errorString() const =0
Kleo::Input
Definition: input.h:49
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal