diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h index a46557cf..28dc6fe9 100644 --- a/kerfuffle/archiveinterface.h +++ b/kerfuffle/archiveinterface.h @@ -1,258 +1,266 @@ /* * Copyright (c) 2007 Henrique Pinto * Copyright (c) 2008-2009 Harald Hvaal * Copyright (c) 2009-2012 Raphael Kubo da Costa * Copyright (c) 2016 Vladyslav Batyrenko * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ARCHIVEINTERFACE_H #define ARCHIVEINTERFACE_H #include "archive_kerfuffle.h" #include "kerfuffle_export.h" #include "archiveentry.h" #include #include #include #include namespace Kerfuffle { class Query; class KERFUFFLE_EXPORT ReadOnlyArchiveInterface: public QObject { Q_OBJECT public: explicit ReadOnlyArchiveInterface(QObject *parent, const QVariantList &args); ~ReadOnlyArchiveInterface() override; /** * Returns the filename of the archive currently being handled. */ QString filename() const; /** * Returns the comment of the archive. */ QString comment() const; /** * @return The password of the archive, if any. */ QString password() const; bool isMultiVolume() const; int numberOfVolumes() const; /** * Returns whether the file can only be read. * * @return @c true The file cannot be written. * @return @c false The file can be read and written. */ virtual bool isReadOnly() const; virtual bool open(); /** * List archive contents. * This runs the process of reading archive contents. * When subclassing, you can block as long as you need (unless you called setWaitForFinishedSignal(true)). * @returns whether the listing succeeded. * @note If returning false, make sure to emit the error() signal beforewards to notify * the user of the error condition. */ virtual bool list() = 0; virtual bool testArchive() = 0; void setPassword(const QString &password); void setHeaderEncryptionEnabled(bool enabled); /** * Extracts the given @p files to the given @p destinationDirectory. * If @p files is empty, the whole archive will be extracted. * When subclassing, you can block as long as you need (unless you called setWaitForFinishedSignal(true)). * @returns whether the extraction succeeded. * @note If returning false, make sure to emit the error() signal beforewards to notify * the user of the error condition. */ virtual bool extractFiles(const QVector &files, const QString &destinationDirectory, const ExtractionOptions &options) = 0; /** * @return Whether the plugins do NOT run the functions in their own thread. * @see setWaitForFinishedSignal() */ bool waitForFinishedSignal(); /** * Returns count of required finish signals for a job to be finished. * * These two methods are used by move and copy jobs, which in some plugins implementations have to call * several processes sequentially. For instance, moving entries in zip archive is only possible if * extracting the entries, deleting them, recreating destination folder structure and adding them back again. */ virtual int moveRequiredSignals() const; virtual int copyRequiredSignals() const; /** * Returns the list of filenames retrieved from the list of entries. */ static QStringList entryFullPaths(const QVector &entries, PathFormat format = WithTrailingSlash); /** * Returns the list of the entries, excluding their children. * * This method relies on entries paths so doesn't require parents to be set. */ static QVector entriesWithoutChildren(const QVector &entries); /** * Returns the string list of entry paths, which will be a result of adding/moving/copying entries. * * @param entries The entries which will be added/moved/copied. * @param destination Destination path within the archive to which entries have to be added. For renaming an entry * the path has to contain a new filename too. * @param entriesWithoutChildren Entries count, excluding their children. For AddJob or CopyJob 0 MUST be passed. * * @return For entries * some/dir/ * some/dir/entry * some/dir/some/entry * some/another/entry * and destination * some/destination * will return * some/destination/dir/ * some/destination/dir/entry * some/destination/dir/some/enty * some/destination/entry */ static QStringList entryPathsFromDestination(QStringList entries, const Archive::Entry *destination, int entriesWithoutChildren); /** * @return true if the interface has killed the job or if it will stop it as soon as possible. * Otherwise returns false if the interface is not able to kill the operation. */ virtual bool doKill(); bool isHeaderEncryptionEnabled() const; virtual QString multiVolumeName() const; void setMultiVolume(bool value); uint numberOfEntries() const; QMimeType mimetype() const; /** * @return Whether the interface supports progress reporting for BatchExtractJobs. */ virtual bool hasBatchExtractionProgress() const; Q_SIGNALS: /** * Emitted when the user cancels the operation. Examples: * - the user cancels the password dialog * - the user cancels the overwrite dialog */ void cancelled(); void error(const QString &message, const QString &details = QString()); void entry(Archive::Entry *archiveEntry); void progress(double progress); void info(const QString &info); void finished(bool result); void testSuccess(); void compressionMethodFound(const QString &method); void encryptionMethodFound(const QString &method); /** * Emitted when @p query needs to be executed on the GUI thread. */ void userQuery(Query *query); protected: /** * Setting this option to true will NOT run the functions in their own thread. * Instead it will be necessary to call finished(bool) when the operation is actually finished. */ void setWaitForFinishedSignal(bool value); void setCorrupt(bool isCorrupt); bool isCorrupt() const; QString m_comment; int m_numberOfVolumes; uint m_numberOfEntries; KPluginMetaData m_metaData; private: QString m_filename; QMimeType m_mimetype; QString m_password; bool m_waitForFinishedSignal; bool m_isHeaderEncryptionEnabled; bool m_isCorrupt; bool m_isMultiVolume; private Q_SLOTS: void onEntry(Archive::Entry *archiveEntry); }; class KERFUFFLE_EXPORT ReadWriteArchiveInterface: public ReadOnlyArchiveInterface { Q_OBJECT public: enum OperationMode { - List, Extract, Add, Move, Copy, Delete, Comment, Test + NoOperation, + List, + Extract, + Add, + Move, + Copy, + Delete, + Comment, + Test }; explicit ReadWriteArchiveInterface(QObject *parent, const QVariantList &args); ~ReadWriteArchiveInterface() override; bool isReadOnly() const override; /** * Adds the given @p files under the given @p destination. * If @p destination is null, the files will be added under the root of the archive. * @param options The compression options that must be respected. * @param numberOfEntriesToAdd The total number of entries the will be added. * @return Whether the operation succeeded. * @note If returning false, make sure to emit the error() signal beforewards to notify * the user of the error condition. */ virtual bool addFiles(const QVector &files, const Archive::Entry *destination, const CompressionOptions& options, uint numberOfEntriesToAdd = 0) = 0; virtual bool moveFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions& options) = 0; virtual bool copyFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions& options) = 0; virtual bool deleteFiles(const QVector &files) = 0; virtual bool addComment(const QString &comment) = 0; Q_SIGNALS: void entryRemoved(const QString &path); private Q_SLOTS: void onEntryRemoved(const QString &path); }; } // namespace Kerfuffle #endif // ARCHIVEINTERFACE_H diff --git a/kerfuffle/cliinterface.h b/kerfuffle/cliinterface.h index b4b18111..030de8ed 100644 --- a/kerfuffle/cliinterface.h +++ b/kerfuffle/cliinterface.h @@ -1,230 +1,230 @@ /* * ark -- archiver for the KDE project * * Copyright (C) 2009 Harald Hvaal * Copyright (C) 2009-2011 Raphael Kubo da Costa * Copyright (c) 2016 Vladyslav Batyrenko * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CLIINTERFACE_H #define CLIINTERFACE_H #include "archiveinterface.h" #include "archiveentry.h" #include "cliproperties.h" #include "kerfuffle_export.h" #include #include class KProcess; class KPtyProcess; class QDir; class QTemporaryDir; class QTemporaryFile; namespace Kerfuffle { class KERFUFFLE_EXPORT CliInterface : public ReadWriteArchiveInterface { Q_OBJECT public: explicit CliInterface(QObject *parent, const QVariantList & args); ~CliInterface() override; int copyRequiredSignals() const override; bool list() override; bool extractFiles(const QVector &files, const QString &destinationDirectory, const ExtractionOptions &options) override; bool addFiles(const QVector &files, const Archive::Entry *destination, const CompressionOptions& options, uint numberOfEntriesToAdd = 0) override; bool moveFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions& options) override; bool copyFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions& options) override; bool deleteFiles(const QVector &files) override; bool addComment(const QString &comment) override; bool testArchive() override; virtual void resetParsing() = 0; virtual bool readListLine(const QString &line) = 0; virtual bool readExtractLine(const QString &line) = 0; virtual bool readDeleteLine(const QString &line); bool doKill() override; /** * Sets if the listing should include empty lines. * * The default value is false. */ void setListEmptyLines(bool emptyLines); /** * Move all files from @p tmpDir to @p destDir, preserving paths if @p preservePaths is true. * @return Whether the operation has been successful. */ bool moveToDestination(const QDir &tempDir, const QDir &destDir, bool preservePaths); /** * @see ArchiveModel::entryPathsFromDestination */ void setNewMovedFiles(const QVector &entries, const Archive::Entry *destination, int entriesWithoutChildren); /** * @return The list of selected files to extract. */ QStringList extractFilesList(const QVector &files) const; QString multiVolumeName() const override; CliProperties *cliProperties() const; protected: bool setAddedFiles(); /** * Handles the given @p line. * @return True if the line is ok. False if the line contains/triggers a "fatal" error * or a canceled user query. If false is returned, the caller is supposed to call killProcess(). */ virtual bool handleLine(const QString& line); /** * Run @p programName with the given @p arguments. * * @param programName The program that will be run (not the whole path). * @param arguments A list of arguments that will be passed to the program. * * @return @c true if the program was found and the process was started correctly, * @c false otherwise (in which case finished(false) is emitted). */ bool runProcess(const QString& programName, const QStringList& arguments); /** * Kill the running process. The finished signal is emitted according to @p emitFinished. */ void killProcess(bool emitFinished = true); /** * Ask the password *before* running any process. * @return True if the user supplies a password, false otherwise (in which case finished() is emitted). */ bool passwordQuery(); void cleanUp(); - OperationMode m_operationMode = List; + OperationMode m_operationMode = NoOperation; CliProperties *m_cliProps = nullptr; QString m_oldWorkingDirExtraction; // Used ONLY by extraction jobs. QString m_oldWorkingDir; // Used by copy and move jobs. QScopedPointer m_tempWorkingDir; QScopedPointer m_tempAddDir; - OperationMode m_subOperation = List; + OperationMode m_subOperation = NoOperation; QVector m_passedFiles; QVector m_tempAddedFiles; Archive::Entry *m_passedDestination = nullptr; CompressionOptions m_passedOptions; #ifdef Q_OS_WIN KProcess *m_process = nullptr; #else KPtyProcess *m_process = nullptr; #endif bool m_abortingOperation = false; protected Q_SLOTS: virtual void readStdout(bool handleAll = false); private: bool handleFileExistsMessage(const QString& filename); /** * Returns a list of path pairs which will be supplied to rn command. * [ ... ] * Also constructs a list of new entries resulted in moving. * * @param entriesWithoutChildren List of archive entries * @param destination Must be a directory entry if QList contains more that one entry */ QStringList entryPathDestinationPairs(const QVector &entriesWithoutChildren, const Archive::Entry *destination); /** * Wrapper around KProcess::write() or KPtyDevice::write(), depending on * the platform. */ void writeToProcess(const QByteArray& data); bool moveDroppedFilesToDest(const QVector &files, const QString &finalDest); /** * @return Whether @p dir is an empty directory. */ bool isEmptyDir(const QDir &dir); /** * Performs any additional escaping and processing on @p fileName * before passing it to the underlying process. * * The default implementation returns @p fileName unchanged. * * @param fileName String to escape. */ virtual QString escapeFileName(const QString &fileName) const; void cleanUpExtracting(); void restoreWorkingDirExtraction(); void finishCopying(bool result); QByteArray m_stdOutData; QRegularExpression m_passwordPromptPattern; QHash > m_patternCache; QVector m_removedFiles; QVector m_newMovedFiles; int m_exitCode = 0; bool m_listEmptyLines = false; QString m_storedFileName; ExtractionOptions m_extractionOptions; QString m_extractDestDir; QScopedPointer m_extractTempDir; QScopedPointer m_commentTempFile; QVector m_extractedFiles; qulonglong m_archiveSizeOnDisk = 0; qulonglong m_listedSize = 0; protected Q_SLOTS: virtual void processFinished(int exitCode, QProcess::ExitStatus exitStatus); private Q_SLOTS: void extractProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); void continueCopying(bool result); void onEntry(Archive::Entry *archiveEntry); }; } #endif /* CLIINTERFACE_H */ diff --git a/plugins/libzipplugin/libzipplugin.h b/plugins/libzipplugin/libzipplugin.h index 5c8196b0..2932741d 100644 --- a/plugins/libzipplugin/libzipplugin.h +++ b/plugins/libzipplugin/libzipplugin.h @@ -1,72 +1,72 @@ /* * Copyright (c) 2017 Ragnar Thomsen * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBZIPPLUGIN_H #define LIBZIPPLUGIN_H #include "archiveinterface.h" #include #include using namespace Kerfuffle; class LibzipPlugin : public ReadWriteArchiveInterface { Q_OBJECT public: explicit LibzipPlugin(QObject *parent, const QVariantList& args); ~LibzipPlugin() override; bool list() override; bool doKill() override; bool extractFiles(const QVector &files, const QString& destinationDirectory, const ExtractionOptions& options) override; bool addFiles(const QVector &files, const Archive::Entry *destination, const CompressionOptions& options, uint numberOfEntriesToAdd = 0) override; bool deleteFiles(const QVector &files) override; bool moveFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions &options) override; bool copyFiles(const QVector &files, Archive::Entry *destination, const CompressionOptions &options) override; bool addComment(const QString& comment) override; bool testArchive() override; private: bool extractEntry(zip_t *archive, const QString &entry, const QString &rootNode, const QString &destDir, bool preservePaths, bool removeRootNode); bool writeEntry(zip_t *archive, const QString &entry, const Archive::Entry* destination, const CompressionOptions& options, bool isDir = false); bool emitEntryForIndex(zip_t *archive, qlonglong index); void progressEmitted(double pct); QString permissionsToString(const mode_t &perm); void setOperationMode(OperationMode operationMode); QVector m_emittedEntries; bool m_overwriteAll; bool m_skipAll; bool m_listAfterAdd; QMutex m_mutex; - OperationMode m_operationMode = List; + OperationMode m_operationMode = NoOperation; }; #endif // LIBZIPPLUGIN_H