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

ark

  • sources
  • kde-4.12
  • kdeutils
  • ark
  • kerfuffle
cliinterface.cpp
Go to the documentation of this file.
1 /*
2  * ark -- archiver for the KDE project
3  *
4  * Copyright (C) 2009 Harald Hvaal <haraldhv@stud.ntnu.no>
5  * Copyright (C) 2009-2011 Raphael Kubo da Costa <rakuco@FreeBSD.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "cliinterface.h"
30 #include "queries.h"
31 
32 #ifdef Q_OS_WIN
33 # include <KProcess>
34 #else
35 # include <KPtyDevice>
36 # include <KPtyProcess>
37 #endif
38 
39 #include <KStandardDirs>
40 #include <KDebug>
41 #include <KLocale>
42 
43 #include <QApplication>
44 #include <QDateTime>
45 #include <QDir>
46 #include <QEventLoop>
47 #include <QFile>
48 #include <QProcess>
49 #include <QThread>
50 #include <QTimer>
51 
52 namespace Kerfuffle
53 {
54 CliInterface::CliInterface(QObject *parent, const QVariantList & args)
55  : ReadWriteArchiveInterface(parent, args),
56  m_process(0),
57  m_listEmptyLines(false)
58 {
59  //because this interface uses the event loop
60  setWaitForFinishedSignal(true);
61 
62  if (QMetaType::type("QProcess::ExitStatus") == 0) {
63  qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
64  }
65 }
66 
67 void CliInterface::cacheParameterList()
68 {
69  m_param = parameterList();
70  Q_ASSERT(m_param.contains(ExtractProgram));
71  Q_ASSERT(m_param.contains(ListProgram));
72  Q_ASSERT(m_param.contains(PreservePathSwitch));
73  Q_ASSERT(m_param.contains(FileExistsExpression));
74  Q_ASSERT(m_param.contains(FileExistsInput));
75 }
76 
77 CliInterface::~CliInterface()
78 {
79  Q_ASSERT(!m_process);
80 }
81 
82 void CliInterface::setListEmptyLines(bool emptyLines)
83 {
84  m_listEmptyLines = emptyLines;
85 }
86 
87 bool CliInterface::list()
88 {
89  cacheParameterList();
90  m_operationMode = List;
91 
92  QStringList args = m_param.value(ListArgs).toStringList();
93  substituteListVariables(args);
94 
95  if (!runProcess(m_param.value(ListProgram).toStringList(), args)) {
96  failOperation();
97  return false;
98  }
99 
100  return true;
101 }
102 
103 bool CliInterface::copyFiles(const QList<QVariant> & files, const QString & destinationDirectory, ExtractionOptions options)
104 {
105  kDebug();
106  cacheParameterList();
107 
108  m_operationMode = Copy;
109 
110  //start preparing the argument list
111  QStringList args = m_param.value(ExtractArgs).toStringList();
112 
113  //now replace the various elements in the list
114  for (int i = 0; i < args.size(); ++i) {
115  QString argument = args.at(i);
116  kDebug() << "Processing argument " << argument;
117 
118  if (argument == QLatin1String( "$Archive" )) {
119  args[i] = filename();
120  }
121 
122  if (argument == QLatin1String( "$PreservePathSwitch" )) {
123  QStringList replacementFlags = m_param.value(PreservePathSwitch).toStringList();
124  Q_ASSERT(replacementFlags.size() == 2);
125 
126  bool preservePaths = options.value(QLatin1String( "PreservePaths" )).toBool();
127  QString theReplacement;
128  if (preservePaths) {
129  theReplacement = replacementFlags.at(0);
130  } else {
131  theReplacement = replacementFlags.at(1);
132  }
133 
134  if (theReplacement.isEmpty()) {
135  args.removeAt(i);
136  --i; //decrement to compensate for the variable we removed
137  } else {
138  //but in this case we don't have to decrement, we just
139  //replace it
140  args[i] = theReplacement;
141  }
142  }
143 
144  if (argument == QLatin1String( "$PasswordSwitch" )) {
145  //if the PasswordSwitch argument has been added, we at least
146  //assume that the format of the switch has been added as well
147  Q_ASSERT(m_param.contains(PasswordSwitch));
148 
149  //we will decrement i afterwards
150  args.removeAt(i);
151 
152  //if we get a hint about this being a password protected archive, ask about
153  //the password in advance.
154  if ((options.value(QLatin1String("PasswordProtectedHint")).toBool()) &&
155  (password().isEmpty())) {
156  kDebug() << "Password hint enabled, querying user";
157 
158  Kerfuffle::PasswordNeededQuery query(filename());
159  emit userQuery(&query);
160  query.waitForResponse();
161 
162  if (query.responseCancelled()) {
163  failOperation();
164  return false;
165  }
166  setPassword(query.password());
167  }
168 
169  QString pass = password();
170 
171  if (!pass.isEmpty()) {
172  QStringList theSwitch = m_param.value(PasswordSwitch).toStringList();
173  for (int j = 0; j < theSwitch.size(); ++j) {
174  //get the argument part
175  QString newArg = theSwitch.at(j);
176 
177  //substitute the $Path
178  newArg.replace(QLatin1String( "$Password" ), pass);
179 
180  //put it in the arg list
181  args.insert(i + j, newArg);
182  ++i;
183 
184  }
185  }
186  --i; //decrement to compensate for the variable we replaced
187  }
188 
189  if (argument == QLatin1String( "$RootNodeSwitch" )) {
190  //if the RootNodeSwitch argument has been added, we at least
191  //assume that the format of the switch has been added as well
192  Q_ASSERT(m_param.contains(RootNodeSwitch));
193 
194  //we will decrement i afterwards
195  args.removeAt(i);
196 
197  QString rootNode;
198  if (options.contains(QLatin1String( "RootNode" ))) {
199  rootNode = options.value(QLatin1String( "RootNode" )).toString();
200  kDebug() << "Set root node " << rootNode;
201  }
202 
203  if (!rootNode.isEmpty()) {
204  QStringList theSwitch = m_param.value(RootNodeSwitch).toStringList();
205  for (int j = 0; j < theSwitch.size(); ++j) {
206  //get the argument part
207  QString newArg = theSwitch.at(j);
208 
209  //substitute the $Path
210  newArg.replace(QLatin1String( "$Path" ), rootNode);
211 
212  //put it in the arg list
213  args.insert(i + j, newArg);
214  ++i;
215 
216  }
217  }
218  --i; //decrement to compensate for the variable we replaced
219  }
220 
221  if (argument == QLatin1String( "$Files" )) {
222  args.removeAt(i);
223  for (int j = 0; j < files.count(); ++j) {
224  args.insert(i + j, escapeFileName(files.at(j).toString()));
225  ++i;
226  }
227  --i;
228  }
229  }
230 
231  kDebug() << "Setting current dir to " << destinationDirectory;
232  QDir::setCurrent(destinationDirectory);
233 
234  if (!runProcess(m_param.value(ExtractProgram).toStringList(), args)) {
235  failOperation();
236  return false;
237  }
238 
239  return true;
240 }
241 
242 bool CliInterface::addFiles(const QStringList & files, const CompressionOptions& options)
243 {
244  cacheParameterList();
245 
246  m_operationMode = Add;
247 
248  const QString globalWorkDir = options.value(QLatin1String( "GlobalWorkDir" )).toString();
249  const QDir workDir = globalWorkDir.isEmpty() ? QDir::current() : QDir(globalWorkDir);
250  if (!globalWorkDir.isEmpty()) {
251  kDebug() << "GlobalWorkDir is set, changing dir to " << globalWorkDir;
252  QDir::setCurrent(globalWorkDir);
253  }
254 
255  //start preparing the argument list
256  QStringList args = m_param.value(AddArgs).toStringList();
257 
258  //now replace the various elements in the list
259  for (int i = 0; i < args.size(); ++i) {
260  const QString argument = args.at(i);
261  kDebug() << "Processing argument " << argument;
262 
263  if (argument == QLatin1String( "$Archive" )) {
264  args[i] = filename();
265  }
266 
267  if (argument == QLatin1String( "$Files" )) {
268  args.removeAt(i);
269  for (int j = 0; j < files.count(); ++j) {
270  // #191821: workDir must be used instead of QDir::current()
271  // so that symlinks aren't resolved automatically
272  // TODO: this kind of call should be moved upwards in the
273  // class hierarchy to avoid code duplication
274  const QString relativeName =
275  workDir.relativeFilePath(files.at(j));
276 
277  args.insert(i + j, relativeName);
278  ++i;
279  }
280  --i;
281  }
282  }
283 
284  if (!runProcess(m_param.value(AddProgram).toStringList(), args)) {
285  failOperation();
286  return false;
287  }
288 
289  return true;
290 }
291 
292 bool CliInterface::deleteFiles(const QList<QVariant> & files)
293 {
294  cacheParameterList();
295  m_operationMode = Delete;
296 
297  //start preparing the argument list
298  QStringList args = m_param.value(DeleteArgs).toStringList();
299 
300  //now replace the various elements in the list
301  for (int i = 0; i < args.size(); ++i) {
302  QString argument = args.at(i);
303  kDebug() << "Processing argument " << argument;
304 
305  if (argument == QLatin1String( "$Archive" )) {
306  args[i] = filename();
307  } else if (argument == QLatin1String( "$Files" )) {
308  args.removeAt(i);
309  for (int j = 0; j < files.count(); ++j) {
310  args.insert(i + j, escapeFileName(files.at(j).toString()));
311  ++i;
312  }
313  --i;
314  }
315  }
316 
317  m_removedFiles = files;
318 
319  if (!runProcess(m_param.value(DeleteProgram).toStringList(), args)) {
320  failOperation();
321  return false;
322  }
323 
324  return true;
325 }
326 
327 bool CliInterface::runProcess(const QStringList& programNames, const QStringList& arguments)
328 {
329  QString programPath;
330  for (int i = 0; i < programNames.count(); i++) {
331  programPath = KStandardDirs::findExe(programNames.at(i));
332  if (!programPath.isEmpty())
333  break;
334  }
335  if (programPath.isEmpty()) {
336  const QString names = programNames.join(QLatin1String(", "));
337  emit error(i18ncp("@info", "Failed to locate program <filename>%2</filename> on disk.",
338  "Failed to locate programs <filename>%2</filename> on disk.", programNames.count(), names));
339  emit finished(false);
340  return false;
341  }
342 
343  kDebug() << "Executing" << programPath << arguments;
344 
345  if (m_process) {
346  m_process->waitForFinished();
347  delete m_process;
348  }
349 
350 #ifdef Q_OS_WIN
351  m_process = new KProcess;
352 #else
353  m_process = new KPtyProcess;
354  m_process->setPtyChannels(KPtyProcess::StdinChannel);
355 #endif
356 
357  m_process->setOutputChannelMode(KProcess::MergedChannels);
358  m_process->setNextOpenMode(QIODevice::ReadWrite | QIODevice::Unbuffered | QIODevice::Text);
359  m_process->setProgram(programPath, arguments);
360 
361  connect(m_process, SIGNAL(readyReadStandardOutput()), SLOT(readStdout()), Qt::DirectConnection);
362  connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(processFinished(int,QProcess::ExitStatus)), Qt::DirectConnection);
363 
364  m_stdOutData.clear();
365 
366  m_process->start();
367 
368 #ifdef Q_OS_WIN
369  bool ret = m_process->waitForFinished(-1);
370 #else
371  QEventLoop loop;
372  bool ret = (loop.exec(QEventLoop::WaitForMoreEvents | QEventLoop::ExcludeUserInputEvents) == 0);
373 #endif
374 
375  Q_ASSERT(!m_process);
376 
377  return ret;
378 }
379 
380 void CliInterface::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
381 {
382  kDebug() << exitCode << exitStatus;
383 
384  //if the m_process pointer is gone, then there is nothing to worry
385  //about here
386  if (!m_process) {
387  return;
388  }
389 
390  if (m_operationMode == Delete) {
391  foreach(const QVariant& v, m_removedFiles) {
392  emit entryRemoved(v.toString());
393  }
394  }
395 
396  //handle all the remaining data in the process
397  readStdout(true);
398 
399  delete m_process;
400  m_process = 0;
401 
402  emit progress(1.0);
403 
404  if (m_operationMode == Add) {
405  list();
406  return;
407  }
408 
409  //and we're finished
410  emit finished(true);
411 }
412 
413 void CliInterface::failOperation()
414 {
415  // TODO: Would be good to unit test #304764/#304178.
416  kDebug();
417  doKill();
418 }
419 
420 void CliInterface::readStdout(bool handleAll)
421 {
422  //when hacking this function, please remember the following:
423  //- standard output comes in unpredictable chunks, this is why
424  //you can never know if the last part of the output is a complete line or not
425  //- console applications are not really consistent about what
426  //characters they send out (newline, backspace, carriage return,
427  //etc), so keep in mind that this function is supposed to handle
428  //all those special cases and be the lowest common denominator
429 
430  Q_ASSERT(m_process);
431 
432  if (!m_process->bytesAvailable()) {
433  //if process has no more data, we can just bail out
434  return;
435  }
436 
437  //if the process is still not finished (m_process is appearantly not
438  //set to NULL if here), then the operation should definitely not be in
439  //the main thread as this would freeze everything. assert this.
440  Q_ASSERT(QThread::currentThread() != QApplication::instance()->thread());
441 
442  QByteArray dd = m_process->readAllStandardOutput();
443  m_stdOutData += dd;
444 
445  QList<QByteArray> lines = m_stdOutData.split('\n');
446 
447  //The reason for this check is that archivers often do not end
448  //queries (such as file exists, wrong password) on a new line, but
449  //freeze waiting for input. So we check for errors on the last line in
450  //all cases.
451  // TODO: QLatin1String() might not be the best choice here.
452  // The call to handleLine() at the end of the method uses
453  // QString::fromLocal8Bit(), for example.
454  // TODO: The same check methods are called in handleLine(), this
455  // is suboptimal.
456  bool foundErrorMessage =
457  (checkForErrorMessage(QLatin1String( lines.last() ), WrongPasswordPatterns) ||
458  checkForErrorMessage(QLatin1String( lines.last() ), ExtractionFailedPatterns) ||
459  checkForPasswordPromptMessage(QLatin1String(lines.last())) ||
460  checkForFileExistsMessage(QLatin1String( lines.last() )));
461 
462  if (foundErrorMessage) {
463  handleAll = true;
464  }
465 
466  //this is complex, here's an explanation:
467  //if there is no newline, then there is no guaranteed full line to
468  //handle in the output. The exception is that it is supposed to handle
469  //all the data, OR if there's been an error message found in the
470  //partial data.
471  if (lines.size() == 1 && !handleAll) {
472  return;
473  }
474 
475  if (handleAll) {
476  m_stdOutData.clear();
477  } else {
478  //because the last line might be incomplete we leave it for now
479  //note, this last line may be an empty string if the stdoutdata ends
480  //with a newline
481  m_stdOutData = lines.takeLast();
482  }
483 
484  foreach(const QByteArray& line, lines) {
485  if (!line.isEmpty() || (m_listEmptyLines && m_operationMode == List)) {
486  handleLine(QString::fromLocal8Bit(line));
487  }
488  }
489 }
490 
491 void CliInterface::handleLine(const QString& line)
492 {
493  // TODO: This should be implemented by each plugin; the way progress is
494  // shown by each CLI application is subject to a lot of variation.
495  if ((m_operationMode == Copy || m_operationMode == Add) && m_param.contains(CaptureProgress) && m_param.value(CaptureProgress).toBool()) {
496  //read the percentage
497  int pos = line.indexOf(QLatin1Char( '%' ));
498  if (pos != -1 && pos > 1) {
499  int percentage = line.mid(pos - 2, 2).toInt();
500  emit progress(float(percentage) / 100);
501  return;
502  }
503  }
504 
505  if (m_operationMode == Copy) {
506  if (checkForPasswordPromptMessage(line)) {
507  kDebug() << "Found a password prompt";
508 
509  Kerfuffle::PasswordNeededQuery query(filename());
510  emit userQuery(&query);
511  query.waitForResponse();
512 
513  if (query.responseCancelled()) {
514  failOperation();
515  return;
516  }
517 
518  setPassword(query.password());
519 
520  const QString response(password() + QLatin1Char('\n'));
521  writeToProcess(response.toLocal8Bit());
522 
523  return;
524  }
525 
526  if (checkForErrorMessage(line, WrongPasswordPatterns)) {
527  kDebug() << "Wrong password!";
528  emit error(i18n("Incorrect password."));
529  failOperation();
530  return;
531  }
532 
533  if (checkForErrorMessage(line, ExtractionFailedPatterns)) {
534  kDebug() << "Error in extraction!!";
535  emit error(i18n("Extraction failed because of an unexpected error."));
536  failOperation();
537  return;
538  }
539 
540  if (handleFileExistsMessage(line)) {
541  return;
542  }
543  }
544 
545  if (m_operationMode == List) {
546  if (checkForPasswordPromptMessage(line)) {
547  kDebug() << "Found a password prompt";
548 
549  Kerfuffle::PasswordNeededQuery query(filename());
550  emit userQuery(&query);
551  query.waitForResponse();
552 
553  if (query.responseCancelled()) {
554  failOperation();
555  return;
556  }
557 
558  setPassword(query.password());
559 
560  const QString response(password() + QLatin1Char('\n'));
561  writeToProcess(response.toLocal8Bit());
562 
563  return;
564  }
565 
566  if (checkForErrorMessage(line, WrongPasswordPatterns)) {
567  kDebug() << "Wrong password!";
568  emit error(i18n("Incorrect password."));
569  failOperation();
570  return;
571  }
572 
573  if (checkForErrorMessage(line, ExtractionFailedPatterns)) {
574  kDebug() << "Error in extraction!!";
575  emit error(i18n("Extraction failed because of an unexpected error."));
576  failOperation();
577  return;
578  }
579 
580  if (handleFileExistsMessage(line)) {
581  return;
582  }
583 
584  readListLine(line);
585  return;
586  }
587 }
588 
589 bool CliInterface::checkForPasswordPromptMessage(const QString& line)
590 {
591  const QString passwordPromptPattern(m_param.value(PasswordPromptPattern).toString());
592 
593  if (passwordPromptPattern.isEmpty())
594  return false;
595 
596  if (m_passwordPromptPattern.isEmpty()) {
597  m_passwordPromptPattern.setPattern(m_param.value(PasswordPromptPattern).toString());
598  }
599 
600  if (m_passwordPromptPattern.indexIn(line) != -1) {
601  return true;
602  }
603 
604  return false;
605 }
606 
607 bool CliInterface::checkForFileExistsMessage(const QString& line)
608 {
609  if (m_existsPattern.isEmpty()) {
610  m_existsPattern.setPattern(m_param.value(FileExistsExpression).toString());
611  }
612  if (m_existsPattern.indexIn(line) != -1) {
613  kDebug() << "Detected file existing!! Filename " << m_existsPattern.cap(1);
614  return true;
615  }
616 
617  return false;
618 }
619 
620 bool CliInterface::handleFileExistsMessage(const QString& line)
621 {
622  if (!checkForFileExistsMessage(line)) {
623  return false;
624  }
625 
626  const QString filename = m_existsPattern.cap(1);
627 
628  Kerfuffle::OverwriteQuery query(QDir::current().path() + QLatin1Char( '/' ) + filename);
629  query.setNoRenameMode(true);
630  emit userQuery(&query);
631  kDebug() << "Waiting response";
632  query.waitForResponse();
633 
634  kDebug() << "Finished response";
635 
636  QString responseToProcess;
637  const QStringList choices = m_param.value(FileExistsInput).toStringList();
638 
639  if (query.responseOverwrite()) {
640  responseToProcess = choices.at(0);
641  } else if (query.responseSkip()) {
642  responseToProcess = choices.at(1);
643  } else if (query.responseOverwriteAll()) {
644  responseToProcess = choices.at(2);
645  } else if (query.responseAutoSkip()) {
646  responseToProcess = choices.at(3);
647  } else if (query.responseCancelled()) {
648  if (choices.count() < 5) { // If the program has no way to cancel the extraction, we resort to killing it
649  return doKill();
650  }
651  responseToProcess = choices.at(4);
652  }
653 
654  Q_ASSERT(!responseToProcess.isEmpty());
655 
656  responseToProcess += QLatin1Char( '\n' );
657 
658  writeToProcess(responseToProcess.toLocal8Bit());
659 
660  return true;
661 }
662 
663 bool CliInterface::checkForErrorMessage(const QString& line, int parameterIndex)
664 {
665  QList<QRegExp> patterns;
666 
667  if (m_patternCache.contains(parameterIndex)) {
668  patterns = m_patternCache.value(parameterIndex);
669  } else {
670  if (!m_param.contains(parameterIndex)) {
671  return false;
672  }
673 
674  foreach(const QString& rawPattern, m_param.value(parameterIndex).toStringList()) {
675  patterns << QRegExp(rawPattern);
676  }
677  m_patternCache[parameterIndex] = patterns;
678  }
679 
680  foreach(const QRegExp& pattern, patterns) {
681  if (pattern.indexIn(line) != -1) {
682  return true;
683  }
684  }
685  return false;
686 }
687 
688 bool CliInterface::doKill()
689 {
690  if (m_process) {
691  // Give some time for the application to finish gracefully
692  if (!m_process->waitForFinished(5)) {
693  m_process->kill();
694  }
695 
696  return true;
697  }
698 
699  return false;
700 }
701 
702 bool CliInterface::doSuspend()
703 {
704  return false;
705 }
706 
707 bool CliInterface::doResume()
708 {
709  return false;
710 }
711 
712 void CliInterface::substituteListVariables(QStringList& params)
713 {
714  for (int i = 0; i < params.size(); ++i) {
715  const QString parameter = params.at(i);
716 
717  if (parameter == QLatin1String( "$Archive" )) {
718  params[i] = filename();
719  }
720  }
721 }
722 
723 QString CliInterface::escapeFileName(const QString& fileName) const
724 {
725  return fileName;
726 }
727 
728 void CliInterface::writeToProcess(const QByteArray& data)
729 {
730  Q_ASSERT(m_process);
731  Q_ASSERT(!data.isNull());
732 
733  kDebug() << "Writing" << data << "to the process";
734 
735 #ifdef Q_OS_WIN
736  m_process->write(data);
737 #else
738  m_process->pty()->write(data);
739 #endif
740 }
741 
742 }
743 
744 #include "cliinterface.moc"
cliinterface.h
Kerfuffle::CliInterface::Add
Definition: cliinterface.h:230
Kerfuffle::ReadOnlyArchiveInterface::setWaitForFinishedSignal
void setWaitForFinishedSignal(bool value)
Setting this option to true will not exit the thread with the exit of the various functions...
Definition: archiveinterface.cpp:105
Kerfuffle::ExtractionFailedPatterns
QStringList Default: empty A list of regexp patterns that will cause the extraction to exit with a ge...
Definition: cliinterface.h:194
Kerfuffle::ExtractProgram
QStringList The names to the program that will handle extracting of this archive (eg "rar")...
Definition: cliinterface.h:84
Kerfuffle::CliInterface::CliInterface
CliInterface(QObject *parent, const QVariantList &args)
Definition: cliinterface.cpp:54
Kerfuffle::ReadOnlyArchiveInterface::entryRemoved
void entryRemoved(const QString &path)
Kerfuffle::AddProgram
QStringList The names to the program that will handle adding in this archive format (eg "rar")...
Definition: cliinterface.h:210
Kerfuffle::ListArgs
QStringList The arguments that are passed to the program above for listing the archive.
Definition: cliinterface.h:75
Kerfuffle::PasswordNeededQuery::password
QString password()
Definition: queries.cpp:195
Kerfuffle::ReadOnlyArchiveInterface::userQuery
void userQuery(Query *query)
Kerfuffle::PasswordPromptPattern
QString Default: empty A regexp pattern that matches the program's password prompt.
Definition: cliinterface.h:58
Kerfuffle::ReadOnlyArchiveInterface::filename
QString filename() const
Returns the filename of the archive currently being handled.
Definition: archiveinterface.cpp:48
queries.h
QObject
Kerfuffle::CliInterface::doSuspend
bool doSuspend()
Definition: cliinterface.cpp:702
Kerfuffle::CliInterface::parameterList
virtual ParameterList parameterList() const =0
Kerfuffle::PasswordNeededQuery::responseCancelled
bool responseCancelled()
Definition: queries.cpp:200
Kerfuffle::ReadOnlyArchiveInterface::password
QString password() const
Definition: archiveinterface.cpp:68
Kerfuffle::Query::waitForResponse
void waitForResponse()
Will block until the response have been set.
Definition: queries.cpp:50
Kerfuffle::ReadWriteArchiveInterface
Definition: archiveinterface.h:121
Kerfuffle::PreservePathSwitch
QStringList This should be a qstringlist with either two elements.
Definition: cliinterface.h:122
Kerfuffle::CliInterface::readListLine
virtual bool readListLine(const QString &line)=0
Kerfuffle::ReadOnlyArchiveInterface::setPassword
void setPassword(const QString &password)
Definition: archiveinterface.cpp:63
Kerfuffle::WrongPasswordPatterns
QStringList Default: empty A list of regexp patterns that will alert the user that the password was w...
Definition: cliinterface.h:201
Kerfuffle::CliInterface::copyFiles
virtual bool copyFiles(const QList< QVariant > &files, const QString &destinationDirectory, ExtractionOptions options)
Extract files from archive.
Definition: cliinterface.cpp:103
Kerfuffle::CliInterface::doResume
bool doResume()
Definition: cliinterface.cpp:707
Kerfuffle::ExtractArgs
QStringList The arguments that are passed to the program above for extracting the archive...
Definition: cliinterface.h:100
Kerfuffle::FileExistsExpression
QString This is a regexp, defining how to recognize a "File already exists" prompt when extracting...
Definition: cliinterface.h:148
Kerfuffle::ReadOnlyArchiveInterface::finished
void finished(bool result)
Kerfuffle::CompressionOptions
QHash< QString, QVariant > CompressionOptions
These are the extra options for doing the compression.
Definition: archive.h:85
Kerfuffle::CliInterface::Copy
Definition: cliinterface.h:230
Kerfuffle::CliInterface::Delete
Definition: cliinterface.h:230
Kerfuffle::CaptureProgress
Bool (default false) Will look for the %-sign in the stdout while working, in the form of (2%...
Definition: cliinterface.h:51
Kerfuffle::CliInterface::List
Definition: cliinterface.h:230
Kerfuffle::CliInterface::~CliInterface
virtual ~CliInterface()
Definition: cliinterface.cpp:77
Kerfuffle::PasswordNeededQuery
Definition: queries.h:99
Kerfuffle::DeleteArgs
QStringList The arguments that are passed to the program above for deleting from the archive...
Definition: cliinterface.h:187
Kerfuffle::PasswordSwitch
QStringList (default empty) The format of the root node switch.
Definition: cliinterface.h:141
Kerfuffle::DeleteProgram
QStringList The names to the program that will handle deleting of elements in this archive format (eg...
Definition: cliinterface.h:178
Kerfuffle::ExtractionOptions
QHash< QString, QVariant > ExtractionOptions
Definition: archive.h:86
Kerfuffle::CliInterface::setListEmptyLines
void setListEmptyLines(bool emptyLines)
Sets if the listing should include empty lines.
Definition: cliinterface.cpp:82
Kerfuffle::FileExistsInput
QStringList The various responses that can be supplied as a response to the "file exists" prompt...
Definition: cliinterface.h:169
Kerfuffle::ReadOnlyArchiveInterface::error
void error(const QString &message, const QString &details=QString())
Kerfuffle::CliInterface::m_operationMode
OperationMode m_operationMode
Definition: cliinterface.h:232
Kerfuffle::AddArgs
QStringList The arguments that are passed to the program above for adding to the archive.
Definition: cliinterface.h:219
Kerfuffle::OverwriteQuery
Definition: queries.h:77
Kerfuffle::ReadOnlyArchiveInterface::progress
void progress(double progress)
Kerfuffle::CliInterface::list
virtual bool list()
List archive contents.
Definition: cliinterface.cpp:87
Kerfuffle::CliInterface::addFiles
virtual bool addFiles(const QStringList &files, const CompressionOptions &options)
Definition: cliinterface.cpp:242
Kerfuffle::CliInterface::doKill
bool doKill()
Definition: cliinterface.cpp:688
Kerfuffle::RootNodeSwitch
QStringList (default empty) The format of the root node switch.
Definition: cliinterface.h:130
Kerfuffle::CliInterface::deleteFiles
virtual bool deleteFiles(const QList< QVariant > &files)
Definition: cliinterface.cpp:292
Kerfuffle::ListProgram
QStringList The names to the program that will handle listing of this archive (eg "rar")...
Definition: cliinterface.h:67
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:08:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

ark

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

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

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