File indexing completed on 2024-05-05 17:56:55
0001 /* 0002 SPDX-FileCopyrightText: 2000 Rafi Yanai <krusader@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "fileitem.h" 0009 0010 // QtCore 0011 #include <QCache> 0012 #include <QDateTime> 0013 #include <QMimeDatabase> 0014 #include <QMimeType> 0015 0016 #include <KConfigCore/KDesktopFile> 0017 0018 #include "../compat.h" 0019 #include "filesystemprovider.h" 0020 #include "krpermhandler.h" 0021 0022 bool FileItem::userDefinedFolderIcons = true; 0023 0024 // wrapper class; QCache needs objects 0025 class FileSize 0026 { 0027 public: 0028 const KIO::filesize_t m_size; 0029 FileSize(KIO::filesize_t size) 0030 : m_size(size) 0031 { 0032 } 0033 }; 0034 0035 // cache for calculated directory sizes; 0036 static QCache<const QUrl, FileSize> s_fileSizeCache(1000); 0037 0038 FileItem::FileItem(const QString &name, 0039 const QUrl &url, 0040 bool isDir, 0041 KIO::filesize_t size, 0042 mode_t mode, 0043 time_t mtime, 0044 time_t ctime, 0045 time_t atime, 0046 time_t btime, 0047 uid_t uid, 0048 gid_t gid, 0049 const QString &owner, 0050 const QString &group, 0051 bool isLink, 0052 const QString &linkDest, 0053 bool isBrokenLink, 0054 const QString &acl, 0055 const QString &defaultAcl) 0056 : m_name(name) 0057 , m_url(url) 0058 , m_isDir(isDir) 0059 , m_size(size) 0060 , m_mode(mode) 0061 , m_mtime(mtime) 0062 , m_ctime(ctime) 0063 , m_atime(atime) 0064 , m_btime(btime) 0065 , m_uid(uid) 0066 , m_gid(gid) 0067 , m_owner(owner) 0068 , m_group(group) 0069 , m_isLink(isLink) 0070 , m_linkDest(linkDest) 0071 , m_isBrokenLink(isBrokenLink) 0072 , m_acl(acl) 0073 , m_defaulfAcl(defaultAcl) 0074 , m_AclLoaded(false) 0075 , m_mimeType() 0076 , m_iconName() 0077 { 0078 m_permissions = KrPermHandler::mode2QString(mode); 0079 0080 if (m_owner.isEmpty()) 0081 m_owner = KrPermHandler::uid2user(m_uid); 0082 0083 if (m_group.isEmpty()) 0084 m_group = KrPermHandler::gid2group(m_gid); 0085 0086 if (m_isDir && !m_isLink) { 0087 m_size = s_fileSizeCache.contains(m_url) ? s_fileSizeCache[m_url]->m_size : -1; 0088 } 0089 } 0090 0091 FileItem *FileItem::createDummy() 0092 { 0093 FileItem *file = new FileItem("..", QUrl(), true, 0, 0, -1, -1, -1, -1); 0094 file->setIconName("go-up"); 0095 return file; 0096 } 0097 0098 FileItem *FileItem::createBroken(const QString &name, const QUrl &url) 0099 { 0100 FileItem *file = new FileItem(name, url, false, 0, 0, -1, -1, -1, -1); 0101 file->setIconName("file-broken"); 0102 return file; 0103 } 0104 0105 FileItem *FileItem::createVirtualDir(const QString &name, const QUrl &url) 0106 { 0107 return new FileItem(name, url, true, 0, 0700, -1, -1, -1, -1, getuid(), getgid()); 0108 } 0109 0110 FileItem *FileItem::createCopy(const FileItem &file, const QString &newName) 0111 { 0112 return new FileItem(newName, 0113 file.getUrl(), 0114 file.isDir(), 0115 file.getSize(), 0116 file.getMode(), 0117 file.getModificationTime(), 0118 file.getChangeTime(), 0119 file.getAccessTime(), 0120 file.getCreationTime(), 0121 file.m_uid, 0122 file.m_gid, 0123 file.getOwner(), 0124 file.getGroup(), 0125 file.isSymLink(), 0126 file.getSymDest(), 0127 file.isBrokenLink()); 0128 } 0129 0130 char FileItem::isReadable() const 0131 { 0132 if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) 0133 return KrPermHandler::readable(m_permissions, m_gid, m_uid); 0134 else 0135 return KrPermHandler::ftpReadable(m_owner, m_url.userName(), m_permissions); 0136 } 0137 0138 char FileItem::isWriteable() const 0139 { 0140 if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) 0141 return KrPermHandler::writeable(m_permissions, m_gid, m_uid); 0142 else 0143 return KrPermHandler::ftpWriteable(m_owner, m_url.userName(), m_permissions); 0144 } 0145 0146 char FileItem::isExecutable() const 0147 { 0148 if (m_uid != (uid_t)-1 && m_gid != (gid_t)-1) 0149 return KrPermHandler::executable(m_permissions, m_gid, m_uid); 0150 else 0151 return KrPermHandler::ftpExecutable(m_owner, m_url.userName(), m_permissions); 0152 } 0153 0154 void FileItem::setSize(KIO::filesize_t size) 0155 { 0156 m_size = size; 0157 s_fileSizeCache.insert(m_url, new FileSize(size)); 0158 } 0159 0160 const QString &FileItem::getMime() 0161 { 0162 if (m_mimeType.isEmpty()) { 0163 if (m_isDir) { 0164 m_mimeType = "inode/directory"; 0165 m_iconName = "inode-directory"; 0166 } else if (isBrokenLink()) { 0167 m_mimeType = "unknown"; 0168 m_iconName = "file-broken"; 0169 } else { 0170 const QMimeDatabase db; 0171 const QMimeType mt = db.mimeTypeForUrl(getUrl()); 0172 m_mimeType = mt.isValid() ? mt.name() : "unknown"; 0173 m_iconName = mt.isValid() ? mt.iconName() : "file-broken"; 0174 0175 if (m_mimeType == "inode/directory") { 0176 // TODO view update needed? and does this ever happen? 0177 m_isDir = true; 0178 } 0179 } 0180 0181 if (m_isDir && userDefinedFolderIcons) { 0182 const QUrl url = getUrl(); 0183 if (url.isLocalFile()) { 0184 const QString file = url.toLocalFile() + "/.directory"; 0185 const KDesktopFile cfg(file); 0186 const QString iconName = cfg.readIcon(); 0187 if (!iconName.isEmpty()) 0188 m_iconName = iconName.startsWith(QLatin1String("./")) ? 0189 // relative path 0190 url.toLocalFile() + '/' + iconName 0191 : iconName; 0192 } 0193 } 0194 } 0195 return m_mimeType; 0196 } 0197 0198 const QString &FileItem::getIcon() 0199 { 0200 if (m_iconName.isEmpty()) { 0201 getMime(); // sets the icon 0202 } 0203 return m_iconName; 0204 } 0205 0206 const QString &FileItem::getACL() 0207 { 0208 if (!m_AclLoaded) 0209 loadACL(); 0210 return m_acl; 0211 } 0212 0213 void FileItem::loadACL() 0214 { 0215 if (m_url.isLocalFile()) { 0216 FileSystemProvider::getACL(this, m_acl, m_defaulfAcl); 0217 } 0218 m_AclLoaded = true; 0219 } 0220 0221 const KIO::UDSEntry FileItem::getEntry() 0222 { 0223 KIO::UDSEntry entry; 0224 0225 entry.fastInsert(KIO::UDSEntry::UDS_NAME, getName()); 0226 entry.fastInsert(KIO::UDSEntry::UDS_SIZE, getSize()); 0227 entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, getModificationTime()); 0228 if (m_btime != -1) { 0229 entry.fastInsert(KIO::UDSEntry::UDS_CREATION_TIME, getCreationTime()); 0230 } 0231 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, getAccessTime()); 0232 entry.fastInsert(KIO::UDSEntry::UDS_USER, getOwner()); 0233 entry.fastInsert(KIO::UDSEntry::UDS_GROUP, getGroup()); 0234 entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, getMime()); 0235 entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, getMode() & S_IFMT); 0236 entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, getMode() & 07777); 0237 0238 if (isSymLink()) 0239 entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, getSymDest()); 0240 0241 if (!m_AclLoaded) 0242 loadACL(); 0243 if (!m_acl.isNull() || !m_defaulfAcl.isNull()) { 0244 entry.fastInsert(KIO::UDSEntry::UDS_EXTENDED_ACL, 1); 0245 0246 if (!m_acl.isNull()) 0247 entry.fastInsert(KIO::UDSEntry::UDS_ACL_STRING, m_acl); 0248 0249 if (!m_defaulfAcl.isNull()) 0250 entry.fastInsert(KIO::UDSEntry::UDS_DEFAULT_ACL_STRING, m_defaulfAcl); 0251 } 0252 0253 return entry; 0254 }