File indexing completed on 2025-02-16 13:00:37
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2014 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "krcc.h" 0008 #include "karchive_p.h" 0009 #include "loggingcategory.h" 0010 0011 #include <QDateTime> 0012 #include <QDebug> 0013 #include <QDir> 0014 #include <QFile> 0015 #include <QFileInfo> 0016 #include <QResource> 0017 #include <QUuid> 0018 0019 class Q_DECL_HIDDEN KRcc::KRccPrivate 0020 { 0021 public: 0022 KRccPrivate() 0023 { 0024 } 0025 void createEntries(const QDir &dir, KArchiveDirectory *parentDir, KRcc *q); 0026 0027 QString m_prefix; // '/' + uuid 0028 }; 0029 0030 /** 0031 * A KRccFileEntry represents a file in a rcc archive. 0032 */ 0033 class KRccFileEntry : public KArchiveFile 0034 { 0035 public: 0036 KRccFileEntry(KArchive *archive, 0037 const QString &name, 0038 int access, 0039 const QDateTime &date, 0040 const QString &user, 0041 const QString &group, 0042 qint64 size, 0043 const QString &resourcePath) 0044 : KArchiveFile(archive, name, access, date, user, group, QString(), 0, size) 0045 , m_resourcePath(resourcePath) 0046 { 0047 } 0048 0049 QByteArray data() const override 0050 { 0051 QFile f(m_resourcePath); 0052 if (f.open(QIODevice::ReadOnly)) { 0053 return f.readAll(); 0054 } 0055 qCWarning(KArchiveLog) << "Couldn't open" << m_resourcePath; 0056 return QByteArray(); 0057 } 0058 QIODevice *createDevice() const override 0059 { 0060 return new QFile(m_resourcePath); 0061 } 0062 0063 private: 0064 QString m_resourcePath; 0065 }; 0066 0067 KRcc::KRcc(const QString &filename) 0068 : KArchive(filename) 0069 , d(new KRccPrivate) 0070 { 0071 } 0072 0073 KRcc::~KRcc() 0074 { 0075 if (isOpen()) { 0076 close(); 0077 } 0078 delete d; 0079 } 0080 0081 bool KRcc::doPrepareWriting(const QString &, const QString &, const QString &, qint64, mode_t, const QDateTime &, const QDateTime &, const QDateTime &) 0082 { 0083 setErrorString(tr("Cannot write to RCC file")); 0084 qCWarning(KArchiveLog) << "doPrepareWriting not implemented for KRcc"; 0085 return false; 0086 } 0087 0088 bool KRcc::doFinishWriting(qint64) 0089 { 0090 setErrorString(tr("Cannot write to RCC file")); 0091 qCWarning(KArchiveLog) << "doFinishWriting not implemented for KRcc"; 0092 return false; 0093 } 0094 0095 bool KRcc::doWriteDir(const QString &, const QString &, const QString &, mode_t, const QDateTime &, const QDateTime &, const QDateTime &) 0096 { 0097 setErrorString(tr("Cannot write to RCC file")); 0098 qCWarning(KArchiveLog) << "doWriteDir not implemented for KRcc"; 0099 return false; 0100 } 0101 0102 bool KRcc::doWriteSymLink(const QString &, const QString &, const QString &, const QString &, mode_t, const QDateTime &, const QDateTime &, const QDateTime &) 0103 { 0104 setErrorString(tr("Cannot write to RCC file")); 0105 qCWarning(KArchiveLog) << "doWriteSymLink not implemented for KRcc"; 0106 return false; 0107 } 0108 0109 bool KRcc::openArchive(QIODevice::OpenMode mode) 0110 { 0111 // Open archive 0112 0113 if (mode == QIODevice::WriteOnly) { 0114 return true; 0115 } 0116 if (mode != QIODevice::ReadOnly && mode != QIODevice::ReadWrite) { 0117 setErrorString(tr("Unsupported mode %1").arg(mode)); 0118 return false; 0119 } 0120 0121 QUuid uuid = QUuid::createUuid(); 0122 d->m_prefix = QLatin1Char('/') + uuid.toString(); 0123 if (!QResource::registerResource(fileName(), d->m_prefix)) { 0124 setErrorString(tr("Failed to register resource %1 under prefix %2").arg(fileName(), d->m_prefix)); 0125 return false; 0126 } 0127 0128 QDir dir(QLatin1Char(':') + d->m_prefix); 0129 d->createEntries(dir, rootDir(), this); 0130 return true; 0131 } 0132 0133 void KRcc::KRccPrivate::createEntries(const QDir &dir, KArchiveDirectory *parentDir, KRcc *q) 0134 { 0135 for (const QString &fileName : dir.entryList()) { 0136 const QString entryPath = dir.path() + QLatin1Char('/') + fileName; 0137 const QFileInfo info(entryPath); 0138 if (info.isFile()) { 0139 KArchiveEntry *entry = new KRccFileEntry(q, fileName, 0444, info.lastModified(), parentDir->user(), parentDir->group(), info.size(), entryPath); 0140 parentDir->addEntry(entry); 0141 } else { 0142 KArchiveDirectory *entry = 0143 new KArchiveDirectory(q, fileName, 0555, info.lastModified(), parentDir->user(), parentDir->group(), /*symlink*/ QString()); 0144 if (parentDir->addEntryV2(entry)) { 0145 createEntries(QDir(entryPath), entry, q); 0146 } 0147 } 0148 } 0149 } 0150 0151 bool KRcc::closeArchive() 0152 { 0153 // Close the archive 0154 QResource::unregisterResource(fileName(), d->m_prefix); 0155 // ignore errors 0156 return true; 0157 } 0158 0159 void KRcc::virtual_hook(int id, void *data) 0160 { 0161 KArchive::virtual_hook(id, data); 0162 }