File indexing completed on 2024-05-05 05:50:39

0001 /*
0002     SPDX-FileCopyrightText: 2007 Henrique Pinto <henrique.pinto@kdemail.net>
0003     SPDX-FileCopyrightText: 2008-2009 Harald Hvaal <haraldhv@stud.ntnu.no>
0004     SPDX-FileCopyrightText: 2009-2012 Raphael Kubo da Costa <rakuco@FreeBSD.org>
0005     SPDX-FileCopyrightText: 2016 Vladyslav Batyrenko <mvlabat@gmail.com>
0006 
0007     SPDX-License-Identifier: BSD-2-Clause
0008 */
0009 
0010 #ifndef ARCHIVEINTERFACE_H
0011 #define ARCHIVEINTERFACE_H
0012 
0013 #include "archive_kerfuffle.h"
0014 #include "archiveentry.h"
0015 #include "kerfuffle_export.h"
0016 
0017 #include <KPluginMetaData>
0018 
0019 #include <QObject>
0020 #include <QString>
0021 #include <QStringList>
0022 #include <QVariantList>
0023 #include <qplatformdefs.h>
0024 
0025 namespace Kerfuffle
0026 {
0027 class Query;
0028 
0029 enum { PossiblyMaliciousArchiveError = KJob::UserDefinedError + 1, DestinationNotWritableError };
0030 
0031 class KERFUFFLE_EXPORT ReadOnlyArchiveInterface : public QObject
0032 {
0033     Q_OBJECT
0034 public:
0035     explicit ReadOnlyArchiveInterface(QObject *parent, const QVariantList &args);
0036     ~ReadOnlyArchiveInterface() override;
0037 
0038     /**
0039      * Returns the filename of the archive currently being handled.
0040      */
0041     QString filename() const;
0042 
0043     /**
0044      * Returns the comment of the archive.
0045      */
0046     QString comment() const;
0047 
0048     /**
0049      * @return The password of the archive, if any.
0050      */
0051     QString password() const;
0052 
0053     bool isMultiVolume() const;
0054     int numberOfVolumes() const;
0055 
0056     /**
0057      * Returns whether the file can only be read.
0058      *
0059      * @return @c true  The file cannot be written.
0060      * @return @c false The file can be read and written.
0061      */
0062     virtual bool isReadOnly() const;
0063 
0064     virtual bool open();
0065 
0066     /**
0067      * List archive contents.
0068      * This runs the process of reading archive contents.
0069      * When subclassing, you can block as long as you need (unless you called setWaitForFinishedSignal(true)).
0070      * @returns whether the listing succeeded.
0071      * @note If returning false, make sure to emit the error() signal beforewards to notify
0072      * the user of the error condition.
0073      */
0074     virtual bool list() = 0;
0075     virtual bool testArchive() = 0;
0076     void setPassword(const QString &password);
0077     void setHeaderEncryptionEnabled(bool enabled);
0078 
0079     /**
0080      * Extracts the given @p files to the given @p destinationDirectory.
0081      * If @p files is empty, the whole archive will be extracted.
0082      * When subclassing, you can block as long as you need (unless you called setWaitForFinishedSignal(true)).
0083      * @returns whether the extraction succeeded.
0084      * @note If returning false, make sure to emit the error() signal beforewards to notify
0085      * the user of the error condition.
0086      */
0087     virtual bool extractFiles(const QVector<Archive::Entry *> &files, const QString &destinationDirectory, const ExtractionOptions &options) = 0;
0088 
0089     /**
0090      * @return Whether the plugins do NOT run the functions in their own thread.
0091      * @see setWaitForFinishedSignal()
0092      */
0093     bool waitForFinishedSignal();
0094 
0095     /**
0096      * Returns count of required finish signals for a job to be finished.
0097      *
0098      * These two methods are used by move and copy jobs, which in some plugins implementations have to call
0099      * several processes sequentially. For instance, moving entries in zip archive is only possible if
0100      * extracting the entries, deleting them, recreating destination folder structure and adding them back again.
0101      */
0102     virtual int moveRequiredSignals() const;
0103     virtual int copyRequiredSignals() const;
0104 
0105     /**
0106      * Returns the list of filenames retrieved from the list of entries.
0107      */
0108     static QStringList entryFullPaths(const QVector<Archive::Entry *> &entries, PathFormat format = WithTrailingSlash);
0109 
0110     /**
0111      * Returns the list of the entries, excluding their children.
0112      *
0113      * This method relies on entries paths so doesn't require parents to be set.
0114      */
0115     static QVector<Archive::Entry *> entriesWithoutChildren(const QVector<Archive::Entry *> &entries);
0116 
0117     /**
0118      * Returns the string list of entry paths, which will be a result of adding/moving/copying entries.
0119      *
0120      * @param entries The entries which will be added/moved/copied.
0121      * @param destination Destination path within the archive to which entries have to be added. For renaming an entry
0122      * the path has to contain a new filename too.
0123      * @param entriesWithoutChildren Entries count, excluding their children. For AddJob or CopyJob 0 MUST be passed.
0124      *
0125      * @return For entries
0126      *  some/dir/
0127      *  some/dir/entry
0128      *  some/dir/some/entry
0129      *  some/another/entry
0130      * and destination
0131      *  some/destination
0132      * will return
0133      *  some/destination/dir/
0134      *  some/destination/dir/entry
0135      *  some/destination/dir/some/enty
0136      *  some/destination/entry
0137      */
0138     static QStringList entryPathsFromDestination(QStringList entries, const Archive::Entry *destination, int entriesWithoutChildren);
0139 
0140     /**
0141      * @return true if the interface has killed the job.
0142      * Otherwise returns false if the interface is not able to instantly kill the operation.
0143      */
0144     virtual bool doKill();
0145 
0146     bool isHeaderEncryptionEnabled() const;
0147     virtual QString multiVolumeName() const;
0148     void setMultiVolume(bool value);
0149     uint numberOfEntries() const;
0150     QMimeType mimetype() const;
0151 
0152     /**
0153      * @return Whether the interface supports progress reporting for BatchExtractJobs.
0154      */
0155     virtual bool hasBatchExtractionProgress() const;
0156 
0157     /**
0158      * @return Whether the archive is locked (RAR feature).
0159      */
0160     virtual bool isLocked() const;
0161 
0162     /**
0163      * Returns the size of the unpacked archive
0164      */
0165     qulonglong unpackedSize() const;
0166 
0167     static QString permissionsToString(mode_t perm);
0168 
0169 Q_SIGNALS:
0170 
0171     /**
0172      * Emitted when the user cancels the operation. Examples:
0173      * - the user cancels the password dialog
0174      * - the user cancels the overwrite dialog
0175      */
0176     void cancelled();
0177     void error(const QString &message, const QString &details = QString(), int errorCode = KJob::UserDefinedError);
0178     void entry(Archive::Entry *archiveEntry);
0179     void progress(double progress);
0180     void info(const QString &info);
0181     void finished(bool result);
0182     void testSuccess();
0183     void compressionMethodFound(const QString &method);
0184     void encryptionMethodFound(const QString &method);
0185 
0186     /**
0187      * Emitted when @p query needs to be executed on the GUI thread.
0188      */
0189     void userQuery(Kerfuffle::Query *query);
0190 
0191 protected:
0192     /**
0193      * Setting this option to true will NOT run the functions in their own thread.
0194      * Instead it will be necessary to call finished(bool) when the operation is actually finished.
0195      */
0196     void setWaitForFinishedSignal(bool value);
0197 
0198     void setCorrupt(bool isCorrupt);
0199     bool isCorrupt() const;
0200     QString m_comment;
0201     int m_numberOfVolumes;
0202     uint m_numberOfEntries;
0203     KPluginMetaData m_metaData;
0204 
0205 private:
0206     QString m_filename;
0207     QMimeType m_mimetype;
0208     QString m_password;
0209     bool m_waitForFinishedSignal;
0210     bool m_isHeaderEncryptionEnabled;
0211     bool m_isCorrupt;
0212     bool m_isMultiVolume;
0213     qulonglong m_unpackedSize;
0214 
0215 private Q_SLOTS:
0216     void onEntry(Archive::Entry *archiveEntry);
0217 };
0218 
0219 class KERFUFFLE_EXPORT ReadWriteArchiveInterface : public ReadOnlyArchiveInterface
0220 {
0221     Q_OBJECT
0222 public:
0223     enum OperationMode {
0224         NoOperation,
0225         List,
0226         Extract,
0227         Add,
0228         Move,
0229         Copy,
0230         Delete,
0231         Comment,
0232         Test,
0233     };
0234 
0235     explicit ReadWriteArchiveInterface(QObject *parent, const QVariantList &args);
0236     ~ReadWriteArchiveInterface() override;
0237 
0238     bool isReadOnly() const override;
0239 
0240     /**
0241      * Adds the given @p files under the given @p destination.
0242      * If @p destination is null, the files will be added under the root of the archive.
0243      * @param options The compression options that must be respected.
0244      * @param numberOfEntriesToAdd The total number of entries the will be added.
0245      * @return Whether the operation succeeded.
0246      * @note If returning false, make sure to emit the error() signal beforewards to notify
0247      * the user of the error condition.
0248      */
0249     virtual bool
0250     addFiles(const QVector<Archive::Entry *> &files, const Archive::Entry *destination, const CompressionOptions &options, uint numberOfEntriesToAdd = 0) = 0;
0251     virtual bool moveFiles(const QVector<Archive::Entry *> &files, Archive::Entry *destination, const CompressionOptions &options) = 0;
0252     virtual bool copyFiles(const QVector<Archive::Entry *> &files, Archive::Entry *destination, const CompressionOptions &options) = 0;
0253     virtual bool deleteFiles(const QVector<Archive::Entry *> &files) = 0;
0254     virtual bool addComment(const QString &comment) = 0;
0255 
0256 Q_SIGNALS:
0257     void entryRemoved(const QString &path);
0258 
0259 protected:
0260     OperationMode m_operationMode = NoOperation;
0261 
0262 private Q_SLOTS:
0263     void onEntryRemoved(const QString &path);
0264 };
0265 
0266 } // namespace Kerfuffle
0267 
0268 #endif // ARCHIVEINTERFACE_H