File indexing completed on 2025-02-16 13:00:36
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org> 0003 SPDX-FileCopyrightText: 2003 Leo Savernik <l.savernik@aon.at> 0004 0005 Moved from ktar.h by Roberto Teixeira <maragato@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 #ifndef KARCHIVE_H 0010 #define KARCHIVE_H 0011 0012 #include <sys/stat.h> 0013 #include <sys/types.h> 0014 0015 #include <QCoreApplication> 0016 #include <QDate> 0017 #include <QHash> 0018 #include <QIODevice> 0019 #include <QString> 0020 #include <QStringList> 0021 0022 #include <karchive_export.h> 0023 0024 #ifdef Q_OS_WIN 0025 #include <qplatformdefs.h> // mode_t 0026 #endif 0027 0028 class KArchiveDirectory; 0029 class KArchiveFile; 0030 0031 class KArchivePrivate; 0032 /** 0033 * @class KArchive karchive.h KArchive 0034 * 0035 * KArchive is a base class for reading and writing archives. 0036 * @short generic class for reading/writing archives 0037 * @author David Faure <faure@kde.org> 0038 */ 0039 class KARCHIVE_EXPORT KArchive 0040 { 0041 Q_DECLARE_TR_FUNCTIONS(KArchive) 0042 0043 protected: 0044 /** 0045 * Base constructor (protected since this is a pure virtual class). 0046 * @param fileName is a local path (e.g. "/tmp/myfile.ext"), 0047 * from which the archive will be read from, or into which the archive 0048 * will be written, depending on the mode given to open(). 0049 */ 0050 KArchive(const QString &fileName); 0051 0052 /** 0053 * Base constructor (protected since this is a pure virtual class). 0054 * @param dev the I/O device where the archive reads its data 0055 * Note that this can be a file, but also a data buffer, a compression filter, etc. 0056 * For a file in writing mode it is better to use the other constructor 0057 * though, to benefit from the use of QSaveFile when saving. 0058 */ 0059 KArchive(QIODevice *dev); 0060 0061 public: 0062 virtual ~KArchive(); 0063 0064 /** 0065 * Opens the archive for reading or writing. 0066 * Inherited classes might want to reimplement openArchive instead. 0067 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly 0068 * @see close 0069 */ 0070 virtual bool open(QIODevice::OpenMode mode); 0071 0072 /** 0073 * Closes the archive. 0074 * Inherited classes might want to reimplement closeArchive instead. 0075 * 0076 * @return true if close succeeded without problems 0077 * @see open 0078 */ 0079 virtual bool close(); 0080 0081 /** 0082 * Returns a description of the last error 0083 * @since 5.29 0084 */ 0085 QString errorString() const; 0086 0087 /** 0088 * Checks whether the archive is open. 0089 * @return true if the archive is opened 0090 */ 0091 bool isOpen() const; 0092 0093 /** 0094 * Returns the mode in which the archive was opened 0095 * @return the mode in which the archive was opened (QIODevice::ReadOnly or QIODevice::WriteOnly) 0096 * @see open() 0097 */ 0098 QIODevice::OpenMode mode() const; 0099 0100 /** 0101 * The underlying device. 0102 * @return the underlying device. 0103 */ 0104 QIODevice *device() const; 0105 0106 /** 0107 * The name of the archive file, as passed to the constructor that takes a 0108 * fileName, or an empty string if you used the QIODevice constructor. 0109 * @return the name of the file, or QString() if unknown 0110 */ 0111 QString fileName() const; 0112 0113 /** 0114 * If an archive is opened for reading, then the contents 0115 * of the archive can be accessed via this function. 0116 * @return the directory of the archive 0117 */ 0118 const KArchiveDirectory *directory() const; 0119 0120 /** 0121 * Writes a local file into the archive. The main difference with writeFile, 0122 * is that this method minimizes memory usage, by not loading the whole file 0123 * into memory in one go. 0124 * 0125 * If @p fileName is a symbolic link, it will be written as is, i. e. 0126 * it will not be resolved before. 0127 * @param fileName full path to an existing local file, to be added to the archive. 0128 * @param destName the resulting name (or relative path) of the file in the archive. 0129 */ 0130 bool addLocalFile(const QString &fileName, const QString &destName); 0131 0132 /** 0133 * Writes a local directory into the archive, including all its contents, recursively. 0134 * Calls addLocalFile for each file to be added. 0135 * 0136 * It will also add a @p path that is a symbolic link to a 0137 * directory. The symbolic link will be dereferenced and the content of the 0138 * directory it is pointing to added recursively. However, symbolic links 0139 * *under* @p path will be stored as is. 0140 * @param path full path to an existing local directory, to be added to the archive. 0141 * @param destName the resulting name (or relative path) of the file in the archive. 0142 */ 0143 bool addLocalDirectory(const QString &path, const QString &destName); 0144 0145 /** 0146 * If an archive is opened for writing then you can add new directories 0147 * using this function. KArchive won't write one directory twice. 0148 * 0149 * This method also allows some file metadata to be set. 0150 * However, depending on the archive type not all metadata might be regarded. 0151 * 0152 * @param name the name of the directory 0153 * @param user the user that owns the directory 0154 * @param group the group that owns the directory 0155 * @param perm permissions of the directory 0156 * @param atime time the file was last accessed 0157 * @param mtime modification time of the file 0158 * @param ctime time of last status change 0159 */ 0160 bool writeDir(const QString &name, 0161 const QString &user = QString(), 0162 const QString &group = QString(), 0163 mode_t perm = 040755, 0164 const QDateTime &atime = QDateTime(), 0165 const QDateTime &mtime = QDateTime(), 0166 const QDateTime &ctime = QDateTime()); 0167 0168 /** 0169 * Writes a symbolic link to the archive if supported. 0170 * The archive must be opened for writing. 0171 * 0172 * @param name name of symbolic link 0173 * @param target target of symbolic link 0174 * @param user the user that owns the directory 0175 * @param group the group that owns the directory 0176 * @param perm permissions of the directory 0177 * @param atime time the file was last accessed 0178 * @param mtime modification time of the file 0179 * @param ctime time of last status change 0180 */ 0181 bool writeSymLink(const QString &name, 0182 const QString &target, 0183 const QString &user = QString(), 0184 const QString &group = QString(), 0185 mode_t perm = 0120755, 0186 const QDateTime &atime = QDateTime(), 0187 const QDateTime &mtime = QDateTime(), 0188 const QDateTime &ctime = QDateTime()); 0189 0190 #if KARCHIVE_ENABLE_DEPRECATED_SINCE(5, 0) 0191 /** 0192 * @deprecated since 5.0, use writeFile(const QString&, const QByteArray&, mode_t, const QString&, const QString&, const QDateTime&, const QDateTime&, const 0193 * QDateTime&) 0194 */ 0195 KARCHIVE_DEPRECATED_VERSION(5, 0196 0, 0197 "Use KArchive::writeFile(const QString&, const QByteArray&, mode_t, const QString&, const QString&, const QDateTime&, const " 0198 "QDateTime&, const QDateTime&)") 0199 bool writeFile(const QString &name, 0200 const QString &user, 0201 const QString &group, 0202 const char *data, 0203 qint64 size, 0204 mode_t perm = 0100644, 0205 const QDateTime &atime = QDateTime(), 0206 const QDateTime &mtime = QDateTime(), 0207 const QDateTime &ctime = QDateTime()) 0208 { 0209 QByteArray array(data, size); 0210 return writeFile(name, array, perm, user, group, atime, mtime, ctime); 0211 } 0212 // The above can lead to ambiguous calls when using "..." for the first 4 arguments, 0213 // but that's good, better than unexpected behavior due to the signature change. 0214 #endif 0215 0216 /** 0217 * Writes a new file into the archive. 0218 * 0219 * The archive must be opened for writing first. 0220 * 0221 * The necessary parent directories are created automatically 0222 * if needed. For instance, writing "mydir/test1" does not 0223 * require creating the directory "mydir" first. 0224 * 0225 * This method also allows some file metadata to be 0226 * set. However, depending on the archive type not all metadata might be 0227 * written out. 0228 * 0229 * @param name the name of the file 0230 * @param data the data to write 0231 * @param perm permissions of the file 0232 * @param user the user that owns the file 0233 * @param group the group that owns the file 0234 * @param atime time the file was last accessed 0235 * @param mtime modification time of the file 0236 * @param ctime time of last status change 0237 */ 0238 bool writeFile(const QString &name, 0239 const QByteArray &data, 0240 mode_t perm = 0100644, 0241 const QString &user = QString(), 0242 const QString &group = QString(), 0243 const QDateTime &atime = QDateTime(), 0244 const QDateTime &mtime = QDateTime(), 0245 const QDateTime &ctime = QDateTime()); 0246 0247 /** 0248 * Here's another way of writing a file into an archive: 0249 * Call prepareWriting(), then call writeData() 0250 * as many times as wanted then call finishWriting( totalSize ). 0251 * For tar.gz files, you need to know the size before hand, it is needed in the header! 0252 * For zip files, size isn't used. 0253 * 0254 * This method also allows some file metadata to be 0255 * set. However, depending on the archive type not all metadata might be 0256 * regarded. 0257 * @param name the name of the file 0258 * @param user the user that owns the file 0259 * @param group the group that owns the file 0260 * @param size the size of the file 0261 * @param perm permissions of the file 0262 * @param atime time the file was last accessed 0263 * @param mtime modification time of the file 0264 * @param ctime time of last status change 0265 */ 0266 bool prepareWriting(const QString &name, 0267 const QString &user, 0268 const QString &group, 0269 qint64 size, 0270 mode_t perm = 0100644, 0271 const QDateTime &atime = QDateTime(), 0272 const QDateTime &mtime = QDateTime(), 0273 const QDateTime &ctime = QDateTime()); 0274 0275 /** 0276 * Write data into the current file - to be called after calling prepareWriting 0277 */ 0278 virtual bool writeData(const char *data, qint64 size); 0279 0280 /** 0281 * Call finishWriting after writing the data. 0282 * @param size the size of the file 0283 * @see prepareWriting() 0284 */ 0285 bool finishWriting(qint64 size); 0286 0287 protected: 0288 /** 0289 * Opens an archive for reading or writing. 0290 * Called by open. 0291 * @param mode may be QIODevice::ReadOnly or QIODevice::WriteOnly 0292 */ 0293 virtual bool openArchive(QIODevice::OpenMode mode) = 0; 0294 0295 /** 0296 * Closes the archive. 0297 * Called by close. 0298 */ 0299 virtual bool closeArchive() = 0; 0300 0301 /** 0302 * Sets error description 0303 * @param errorStr error description 0304 * @since 5.29 0305 */ 0306 void setErrorString(const QString &errorStr); 0307 0308 /** 0309 * Retrieves or create the root directory. 0310 * The default implementation assumes that openArchive() did the parsing, 0311 * so it creates a dummy rootdir if none was set (write mode, or no '/' in the archive). 0312 * Reimplement this to provide parsing/listing on demand. 0313 * @return the root directory 0314 */ 0315 virtual KArchiveDirectory *rootDir(); 0316 0317 /** 0318 * Write a directory to the archive. 0319 * This virtual method must be implemented by subclasses. 0320 * 0321 * Depending on the archive type not all metadata might be used. 0322 * 0323 * @param name the name of the directory 0324 * @param user the user that owns the directory 0325 * @param group the group that owns the directory 0326 * @param perm permissions of the directory. Use 040755 if you don't have any other information. 0327 * @param atime time the file was last accessed 0328 * @param mtime modification time of the file 0329 * @param ctime time of last status change 0330 * @see writeDir 0331 */ 0332 virtual bool doWriteDir(const QString &name, 0333 const QString &user, 0334 const QString &group, 0335 mode_t perm, 0336 const QDateTime &atime, 0337 const QDateTime &mtime, 0338 const QDateTime &ctime) = 0; 0339 0340 /** 0341 * Writes a symbolic link to the archive. 0342 * This virtual method must be implemented by subclasses. 0343 * 0344 * @param name name of symbolic link 0345 * @param target target of symbolic link 0346 * @param user the user that owns the directory 0347 * @param group the group that owns the directory 0348 * @param perm permissions of the directory 0349 * @param atime time the file was last accessed 0350 * @param mtime modification time of the file 0351 * @param ctime time of last status change 0352 * @see writeSymLink 0353 */ 0354 virtual bool doWriteSymLink(const QString &name, 0355 const QString &target, 0356 const QString &user, 0357 const QString &group, 0358 mode_t perm, 0359 const QDateTime &atime, 0360 const QDateTime &mtime, 0361 const QDateTime &ctime) = 0; 0362 0363 /** 0364 * This virtual method must be implemented by subclasses. 0365 * 0366 * Depending on the archive type not all metadata might be used. 0367 * 0368 * @param name the name of the file 0369 * @param user the user that owns the file 0370 * @param group the group that owns the file 0371 * @param size the size of the file 0372 * @param perm permissions of the file. Use 0100644 if you don't have any more specific permissions to set. 0373 * @param atime time the file was last accessed 0374 * @param mtime modification time of the file 0375 * @param ctime time of last status change 0376 * @see prepareWriting 0377 */ 0378 virtual bool doPrepareWriting(const QString &name, 0379 const QString &user, 0380 const QString &group, 0381 qint64 size, 0382 mode_t perm, 0383 const QDateTime &atime, 0384 const QDateTime &mtime, 0385 const QDateTime &ctime) = 0; 0386 0387 /** 0388 * Called after writing the data. 0389 * This virtual method must be implemented by subclasses. 0390 * 0391 * @param size the size of the file 0392 * @see finishWriting() 0393 */ 0394 virtual bool doFinishWriting(qint64 size) = 0; 0395 0396 /** 0397 * Ensures that @p path exists, create otherwise. 0398 * This handles e.g. tar files missing directory entries, like mico-2.3.0.tar.gz :) 0399 * @param path the path of the directory 0400 * @return the directory with the given @p path 0401 */ 0402 KArchiveDirectory *findOrCreate(const QString &path); 0403 0404 /** 0405 * Can be reimplemented in order to change the creation of the device 0406 * (when using the fileName constructor). By default this method uses 0407 * QSaveFile when saving, and a simple QFile on reading. 0408 * This method is called by open(). 0409 */ 0410 virtual bool createDevice(QIODevice::OpenMode mode); 0411 0412 /** 0413 * Can be called by derived classes in order to set the underlying device. 0414 * Note that KArchive will -not- own the device, it must be deleted by the derived class. 0415 */ 0416 void setDevice(QIODevice *dev); 0417 0418 /** 0419 * Derived classes call setRootDir from openArchive, 0420 * to set the root directory after parsing an existing archive. 0421 */ 0422 void setRootDir(KArchiveDirectory *rootDir); 0423 0424 protected: 0425 virtual void virtual_hook(int id, void *data); 0426 0427 private: 0428 friend class KArchivePrivate; 0429 KArchivePrivate *const d; 0430 }; 0431 0432 // for source compat 0433 #include "karchivedirectory.h" 0434 #include "karchivefile.h" 0435 0436 #endif