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

libkleo

  • sources
  • kde-4.12
  • kdepim
  • libkleo
  • kleo
checksumdefinition.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  checksumdefinition.cpp
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  Copyright (c) 2010 Klarälvdalens Datakonsult AB
6 
7  Libkleopatra is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of the
10  License, or (at your option) any later version.
11 
12  Libkleopatra 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 along
18  with this program; if not, write to the Free Software Foundation, Inc.,
19  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 "checksumdefinition.h"
34 
35 #include "exception.h"
36 #include "cryptobackendfactory.h"
37 
38 #include <KConfigGroup>
39 #include <KLocalizedString>
40 #include <KGlobal>
41 #include <KConfig>
42 #include <KShell>
43 #include <KStandardDirs>
44 
45 #include <QString>
46 #include <QStringList>
47 #include <QDebug>
48 #include <QFileInfo>
49 #include <QProcess>
50 #include <QByteArray>
51 #include <QMutex>
52 #include <QCoreApplication>
53 
54 #include <boost/shared_ptr.hpp>
55 
56 #ifdef stdin
57 # undef stdin // pah..
58 #endif
59 
60 using namespace Kleo;
61 using namespace boost;
62 
63 static QMutex installPathMutex;
64 Q_GLOBAL_STATIC( QString, _installPath )
65 QString ChecksumDefinition::installPath() {
66  const QMutexLocker locker( &installPathMutex );
67  QString * const ip = _installPath();
68  if ( ip->isEmpty() ) {
69  if ( QCoreApplication::instance() ) {
70  *ip = QCoreApplication::applicationDirPath();
71  } else {
72  qWarning( "checksumdefinition.cpp: installPath() called before QCoreApplication was constructed" );
73  }
74  }
75  return *ip;
76 }
77 void ChecksumDefinition::setInstallPath( const QString & ip ) {
78  const QMutexLocker locker( &installPathMutex );
79  *_installPath() =ip;
80 }
81 
82 
83 // Checksum Definition #N groups
84 static const QLatin1String ID_ENTRY( "id" );
85 static const QLatin1String NAME_ENTRY( "Name" );
86 static const QLatin1String CREATE_COMMAND_ENTRY( "create-command" );
87 static const QLatin1String VERIFY_COMMAND_ENTRY( "verify-command" );
88 static const QLatin1String FILE_PATTERNS_ENTRY( "file-patterns" );
89 static const QLatin1String OUTPUT_FILE_ENTRY( "output-file" );
90 static const QLatin1String FILE_PLACEHOLDER( "%f" );
91 static const QLatin1String INSTALLPATH_PLACEHOLDER( "%I" );
92 static const QLatin1String NULL_SEPARATED_STDIN_INDICATOR( "0|" );
93 static const QLatin1Char NEWLINE_SEPARATED_STDIN_INDICATOR( '|' );
94 
95 // ChecksumOperations group
96 static const QLatin1String CHECKSUM_DEFINITION_ID_ENTRY( "checksum-definition-id" );
97 
98 
99 namespace {
100 
101  class ChecksumDefinitionError : public Kleo::Exception {
102  const QString m_id;
103  public:
104  ChecksumDefinitionError( const QString & id, const QString & message )
105  : Kleo::Exception( GPG_ERR_INV_PARAMETER, i18n("Error in checksum definition %1: %2", id, message ), MessageOnly ),
106  m_id( id )
107  {
108 
109  }
110  ~ChecksumDefinitionError() throw() {}
111 
112  const QString & checksumDefinitionId() const { return m_id; }
113  };
114 
115 }
116 
117 static QString try_extensions( const QString & path ) {
118  static const char exts[][4] = {
119  "", "exe", "bat", "bin", "cmd",
120  };
121  static const size_t numExts = sizeof exts / sizeof *exts ;
122  for ( unsigned int i = 0 ; i < numExts ; ++i ) {
123  const QFileInfo fi( path + QLatin1Char('.') + QLatin1String( exts[i] ) );
124  if ( fi.exists() )
125  return fi.filePath();
126  }
127  return QString();
128 }
129 
130 static void parse_command( QString cmdline, const QString & id, const QString & whichCommand,
131  QString * command, QStringList * prefix, QStringList * suffix, ChecksumDefinition::ArgumentPassingMethod * method )
132 {
133  assert( prefix );
134  assert( suffix );
135  assert( method );
136 
137  KShell::Errors errors;
138  QStringList l;
139 
140  if ( cmdline.startsWith( NULL_SEPARATED_STDIN_INDICATOR ) ) {
141  *method = ChecksumDefinition::NullSeparatedInputFile;
142  cmdline.remove( 0, 2 );
143  } else if ( cmdline.startsWith( NEWLINE_SEPARATED_STDIN_INDICATOR ) ) {
144  *method = ChecksumDefinition::NewlineSeparatedInputFile;
145  cmdline.remove( 0, 1 );
146  } else {
147  *method = ChecksumDefinition::CommandLine;
148  }
149  if ( *method != ChecksumDefinition::CommandLine && cmdline.contains( FILE_PLACEHOLDER ) )
150  throw ChecksumDefinitionError( id, i18n("Cannot use both %f and | in '%1'", whichCommand) );
151  cmdline.replace( FILE_PLACEHOLDER, QLatin1String("__files_go_here__") )
152  .replace( INSTALLPATH_PLACEHOLDER, QLatin1String("__path_goes_here__") );
153  l = KShell::splitArgs( cmdline, KShell::AbortOnMeta|KShell::TildeExpand, &errors );
154  l = l.replaceInStrings( QLatin1String("__files_go_here__"), FILE_PLACEHOLDER );
155  if ( l.indexOf( QRegExp( QLatin1String(".*__path_goes_here__.*") ) ) >= 0 )
156  l = l.replaceInStrings( QLatin1String("__path_goes_here__"), ChecksumDefinition::installPath() );
157  if ( errors == KShell::BadQuoting )
158  throw ChecksumDefinitionError( id, i18n("Quoting error in '%1' entry", whichCommand) );
159  if ( errors == KShell::FoundMeta )
160  throw ChecksumDefinitionError( id, i18n("'%1' too complex (would need shell)", whichCommand) );
161  qDebug() << "ChecksumDefinition[" << id << ']' << l;
162  if ( l.empty() )
163  throw ChecksumDefinitionError( id, i18n("'%1' entry is empty/missing", whichCommand) );
164  const QFileInfo fi1( l.front() );
165  if ( fi1.isAbsolute() )
166  *command = try_extensions( l.front() );
167  else
168  *command = KStandardDirs::findExe( fi1.fileName() );
169  if ( command->isEmpty() )
170  throw ChecksumDefinitionError( id, i18n("'%1' empty or not found", whichCommand) );
171  const int idx1 = l.indexOf( FILE_PLACEHOLDER );
172  if ( idx1 < 0 ) {
173  // none -> append
174  *prefix = l.mid( 1 );
175  } else {
176  *prefix = l.mid( 1, idx1-1 );
177  *suffix = l.mid( idx1+1 );
178  }
179  switch ( *method ) {
180  case ChecksumDefinition::CommandLine:
181  qDebug() << "ChecksumDefinition[" << id << ']' << *command << *prefix << FILE_PLACEHOLDER << *suffix;
182  break;
183  case ChecksumDefinition::NewlineSeparatedInputFile:
184  qDebug() << "ChecksumDefinition[" << id << ']' << "find | " << *command << *prefix;
185  break;
186  case ChecksumDefinition::NullSeparatedInputFile:
187  qDebug() << "ChecksumDefinition[" << id << ']' << "find -print0 | " << *command << *prefix;
188  break;
189  case ChecksumDefinition::NumArgumentPassingMethods:
190  assert( !"Should not happen" );
191  break;
192  }
193 }
194 
195 namespace {
196 
197  class KConfigBasedChecksumDefinition : public ChecksumDefinition {
198  public:
199  explicit KConfigBasedChecksumDefinition( const KConfigGroup & group )
200  : ChecksumDefinition( group.readEntryUntranslated( ID_ENTRY ),
201  group.readEntry( NAME_ENTRY ),
202  group.readEntry( OUTPUT_FILE_ENTRY ),
203  group.readEntry( FILE_PATTERNS_ENTRY, QStringList() ) )
204  {
205  if ( id().isEmpty() )
206  throw ChecksumDefinitionError( group.name(), i18n("'id' entry is empty/missing") );
207  if ( outputFileName().isEmpty() )
208  throw ChecksumDefinitionError( id(), i18n("'output-file' entry is empty/missing") );
209  if ( patterns().empty() )
210  throw ChecksumDefinitionError( id(), i18n("'file-patterns' entry is empty/missing") );
211 
212  // create-command
213  ArgumentPassingMethod method;
214  parse_command( group.readEntry( CREATE_COMMAND_ENTRY ), id(), CREATE_COMMAND_ENTRY,
215  &m_createCommand, &m_createPrefixArguments, &m_createPostfixArguments, &method );
216  setCreateCommandArgumentPassingMethod( method );
217 
218  // verify-command
219  parse_command( group.readEntry( VERIFY_COMMAND_ENTRY ), id(), VERIFY_COMMAND_ENTRY,
220  &m_verifyCommand, &m_verifyPrefixArguments, &m_verifyPostfixArguments, &method );
221  setVerifyCommandArgumentPassingMethod( method );
222  }
223 
224  private:
225  /* reimp */ QString doGetCreateCommand() const { return m_createCommand; }
226  /* reimp */ QStringList doGetCreateArguments( const QStringList & files ) const {
227  return m_createPrefixArguments + files + m_createPostfixArguments;
228  }
229  /* reimp */ QString doGetVerifyCommand() const { return m_verifyCommand; }
230  /* reimp */ QStringList doGetVerifyArguments( const QStringList & files ) const {
231  return m_verifyPrefixArguments + files + m_verifyPostfixArguments;
232  }
233 
234  private:
235  QString m_createCommand, m_verifyCommand;
236  QStringList m_createPrefixArguments, m_createPostfixArguments;
237  QStringList m_verifyPrefixArguments, m_verifyPostfixArguments;
238  };
239 
240 }
241 
242 ChecksumDefinition::ChecksumDefinition( const QString & id, const QString & label, const QString & outputFileName, const QStringList & patterns )
243  : m_id( id ),
244  m_label( label.isEmpty() ? id : label ),
245  m_outputFileName( outputFileName ),
246  m_patterns( patterns ),
247  m_createMethod( CommandLine ),
248  m_verifyMethod( CommandLine )
249 {
250 
251 }
252 
253 ChecksumDefinition::~ChecksumDefinition() {}
254 
255 QString ChecksumDefinition::createCommand() const {
256  return doGetCreateCommand();
257 }
258 
259 QString ChecksumDefinition::verifyCommand() const {
260  return doGetVerifyCommand();
261 }
262 
263 #if 0
264 QStringList ChecksumDefinition::createCommandArguments( const QStringList & files ) const {
265  return doGetCreateArguments( files );
266 }
267 
268 QStringList ChecksumDefinition::verifyCommandArguments( const QStringList & files ) const {
269  return doGetVerifyArguments( files );
270 }
271 #endif
272 
273 static QByteArray make_input( const QStringList & files, char sep ) {
274  QByteArray result;
275  Q_FOREACH( const QString & file, files ) {
276  result += QFile::encodeName( file );
277  result += sep;
278  }
279  return result;
280 }
281 
282 static bool start_command( QProcess * p, const char * functionName,
283  const QString & cmd, const QStringList & args,
284  const QStringList & files, ChecksumDefinition::ArgumentPassingMethod method )
285 {
286  if ( !p ) {
287  qWarning( "%s: process == NULL", functionName );
288  return false;
289  }
290 
291  switch ( method ) {
292 
293  case ChecksumDefinition::NumArgumentPassingMethods:
294  assert( !"Should not happen" );
295 
296  case ChecksumDefinition::CommandLine:
297  qDebug( "[%p] Starting %s %s", p, qPrintable( cmd ), qPrintable( args.join(QLatin1String(" ")) ) );
298  p->start( cmd, args, QIODevice::ReadOnly );
299  return true;
300 
301  case ChecksumDefinition::NewlineSeparatedInputFile:
302  case ChecksumDefinition::NullSeparatedInputFile:
303  p->start( cmd, args, QIODevice::ReadWrite );
304  if ( !p->waitForStarted() )
305  return false;
306  const char sep =
307  method == ChecksumDefinition::NewlineSeparatedInputFile ? '\n' :
308  /* else */ '\0' ;
309  const QByteArray stdin = make_input( files, sep );
310  if ( p->write( stdin ) != stdin.size() )
311  return false;
312  p->closeWriteChannel();
313  return true;
314  }
315 
316  return false; // make compiler happy
317 
318 }
319 
320 bool ChecksumDefinition::startCreateCommand( QProcess * p, const QStringList & files ) const {
321  return start_command( p, Q_FUNC_INFO,
322  doGetCreateCommand(),
323  m_createMethod == CommandLine ? doGetCreateArguments( files ) :
324  /* else */ doGetCreateArguments( QStringList() ),
325  files, m_createMethod );
326 }
327 
328 bool ChecksumDefinition::startVerifyCommand( QProcess * p, const QStringList & files ) const {
329  return start_command( p, Q_FUNC_INFO,
330  doGetVerifyCommand(),
331  m_verifyMethod == CommandLine ? doGetVerifyArguments( files ) :
332  /* else */ doGetVerifyArguments( QStringList() ),
333  files, m_verifyMethod );
334 }
335 
336 // static
337 std::vector< shared_ptr<ChecksumDefinition> > ChecksumDefinition::getChecksumDefinitions() {
338  QStringList errors;
339  return getChecksumDefinitions( errors );
340 }
341 
342 // static
343 std::vector< shared_ptr<ChecksumDefinition> > ChecksumDefinition::getChecksumDefinitions( QStringList & errors ) {
344  std::vector< shared_ptr<ChecksumDefinition> > result;
345  if ( KConfig * config = CryptoBackendFactory::instance()->configObject() ) {
346  const QStringList groups = config->groupList().filter( QRegExp(QLatin1String("^Checksum Definition #")) );
347  result.reserve( groups.size() );
348  Q_FOREACH( const QString & group, groups )
349  try {
350  const shared_ptr<ChecksumDefinition> ad( new KConfigBasedChecksumDefinition( KConfigGroup( config, group ) ) );
351  result.push_back( ad );
352  } catch ( const std::exception & e ) {
353  qDebug() << e.what();
354  errors.push_back( QString::fromLocal8Bit( e.what() ) );
355  } catch ( ... ) {
356  errors.push_back( i18n("Caught unknown exception in group %1", group ) );
357  }
358  }
359  return result;
360 }
361 
362 // static
363 shared_ptr<ChecksumDefinition> ChecksumDefinition::getDefaultChecksumDefinition( const std::vector< shared_ptr<ChecksumDefinition> > & checksumDefinitions ) {
364  const KConfigGroup group( KGlobal::config(), "ChecksumOperations" );
365  const QString checksumDefinitionId = group.readEntry( CHECKSUM_DEFINITION_ID_ENTRY );
366  if ( !checksumDefinitionId.isEmpty() )
367  Q_FOREACH( const shared_ptr<ChecksumDefinition> & cd, checksumDefinitions )
368  if ( cd && cd->id() == checksumDefinitionId )
369  return cd;
370  if ( !checksumDefinitions.empty() )
371  return checksumDefinitions.front();
372  else
373  return shared_ptr<ChecksumDefinition>();
374 }
375 
376 // static
377 void ChecksumDefinition::setDefaultChecksumDefinition( const shared_ptr<ChecksumDefinition> & checksumDefinition ) {
378  if ( !checksumDefinition )
379  return;
380  KConfigGroup group( KGlobal::config(), "ChecksumOperations" );
381  group.writeEntry( CHECKSUM_DEFINITION_ID_ENTRY, checksumDefinition->id() );
382  group.sync();
383 }
384 
Kleo::ChecksumDefinition::startCreateCommand
bool startCreateCommand(QProcess *process, const QStringList &files) const
Definition: checksumdefinition.cpp:320
parse_command
static void parse_command(QString cmdline, const QString &id, const QString &whichCommand, QString *command, QStringList *prefix, QStringList *suffix, ChecksumDefinition::ArgumentPassingMethod *method)
Definition: checksumdefinition.cpp:130
Kleo::ChecksumDefinition::ArgumentPassingMethod
ArgumentPassingMethod
Definition: checksumdefinition.h:57
QMutex
Kleo::ChecksumDefinition::verifyCommand
QString verifyCommand() const
Definition: checksumdefinition.cpp:259
CREATE_COMMAND_ENTRY
static const QLatin1String CREATE_COMMAND_ENTRY("create-command")
ID_ENTRY
static const QLatin1String ID_ENTRY("id")
NAME_ENTRY
static const QLatin1String NAME_ENTRY("Name")
start_command
static bool start_command(QProcess *p, const char *functionName, const QString &cmd, const QStringList &args, const QStringList &files, ChecksumDefinition::ArgumentPassingMethod method)
Definition: checksumdefinition.cpp:282
Kleo::ChecksumDefinition::getChecksumDefinitions
static std::vector< boost::shared_ptr< ChecksumDefinition > > getChecksumDefinitions()
Definition: checksumdefinition.cpp:337
QString
installPathMutex
static QMutex installPathMutex
Definition: checksumdefinition.cpp:63
Kleo::CryptoBackendFactory::instance
static CryptoBackendFactory * instance()
Definition: cryptobackendfactory.cpp:102
FILE_PATTERNS_ENTRY
static const QLatin1String FILE_PATTERNS_ENTRY("file-patterns")
FILE_PLACEHOLDER
static const QLatin1String FILE_PLACEHOLDER("%f")
exception.h
Kleo::ChecksumDefinition
Definition: checksumdefinition.h:51
boost::shared_ptr
Definition: checksumdefinition.h:46
Kleo::ChecksumDefinition::NullSeparatedInputFile
Definition: checksumdefinition.h:60
label
const char * label
Definition: cryptoconfigmodule.cpp:516
Kleo::ChecksumDefinition::createCommand
QString createCommand() const
Definition: checksumdefinition.cpp:255
Kleo::ChecksumDefinition::NewlineSeparatedInputFile
Definition: checksumdefinition.h:59
cryptobackendfactory.h
Kleo::ChecksumDefinition::ChecksumDefinition
ChecksumDefinition(const QString &id, const QString &label, const QString &outputFileName, const QStringList &extensions)
Definition: checksumdefinition.cpp:242
Kleo::ChecksumDefinition::setInstallPath
static void setInstallPath(const QString &ip)
Definition: checksumdefinition.cpp:77
Kleo::ChecksumDefinition::startVerifyCommand
bool startVerifyCommand(QProcess *process, const QStringList &files) const
Definition: checksumdefinition.cpp:328
INSTALLPATH_PLACEHOLDER
static const QLatin1String INSTALLPATH_PLACEHOLDER("%I")
CHECKSUM_DEFINITION_ID_ENTRY
static const QLatin1String CHECKSUM_DEFINITION_ID_ENTRY("checksum-definition-id")
Kleo::ChecksumDefinition::setDefaultChecksumDefinition
static void setDefaultChecksumDefinition(const boost::shared_ptr< ChecksumDefinition > &checksumDefinition)
Definition: checksumdefinition.cpp:377
Kleo::ChecksumDefinition::CommandLine
Definition: checksumdefinition.h:58
VERIFY_COMMAND_ENTRY
static const QLatin1String VERIFY_COMMAND_ENTRY("verify-command")
NEWLINE_SEPARATED_STDIN_INDICATOR
static const QLatin1Char NEWLINE_SEPARATED_STDIN_INDICATOR( '|')
make_input
static QByteArray make_input(const QStringList &files, char sep)
Definition: checksumdefinition.cpp:273
OUTPUT_FILE_ENTRY
static const QLatin1String OUTPUT_FILE_ENTRY("output-file")
Kleo::Exception
Definition: exception.h:45
Kleo::ChecksumDefinition::~ChecksumDefinition
virtual ~ChecksumDefinition()
Definition: checksumdefinition.cpp:253
Kleo::ChecksumDefinition::installPath
static QString installPath()
Definition: checksumdefinition.cpp:65
Kleo::ChecksumDefinition::getDefaultChecksumDefinition
static boost::shared_ptr< ChecksumDefinition > getDefaultChecksumDefinition(const std::vector< boost::shared_ptr< ChecksumDefinition > > &available)
Definition: checksumdefinition.cpp:363
try_extensions
static QString try_extensions(const QString &path)
Definition: checksumdefinition.cpp:117
Kleo::ChecksumDefinition::NumArgumentPassingMethods
Definition: checksumdefinition.h:62
checksumdefinition.h
NULL_SEPARATED_STDIN_INDICATOR
static const QLatin1String NULL_SEPARATED_STDIN_INDICATOR("0|")
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:57:48 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkleo

Skip menu "libkleo"
  • 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