bool QFSFileEnginePrivate::isSymlink() const { if (need_lstat) { QFSFileEnginePrivate *that = const_cast<QFSFileEnginePrivate *>(this); that->need_lstat = false; QT_STATBUF st; // don't clobber our main one that->is_link = (QT_LSTAT(nativeFilePath.constData(), &st) == 0) ? S_ISLNK(st.st_mode) : false; } return is_link; }
// This function should only be called when: // - KFileItem is called with a QUrl object directly! // - refresh is called. // This is done to re-populate the UDSEntry object. void KFileItemPrivate::stat() { if(m_url.isLocalFile()) { QT_STATBUF buf; const QString path = m_url.adjusted(QUrl::StripTrailingSlash).toLocalFile(); const QByteArray pathBA = QFile::encodeName(path); if (QT_LSTAT(pathBA.constData(), &buf) == 0) { m_entry = KIO::UDSEntry(buf, m_url.fileName()); } } }
void KFileItemPrivate::init() { m_access.clear(); // metaInfo = KFileMetaInfo(); // stat() local files if needed // TODO: delay this until requested if (m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown || m_entry.count() == 0) { if (m_url.isLocalFile()) { /* directories may not have a slash at the end if * we want to stat() them; it requires that we * change into it .. which may not be allowed * stat("/is/unaccessible") -> rwx------ * stat("/is/unaccessible/") -> EPERM H.Z. * This is the reason for the StripTrailingSlash */ QT_STATBUF buf; const QString path = m_url.adjusted(QUrl::StripTrailingSlash).toLocalFile(); const QByteArray pathBA = QFile::encodeName(path); if (QT_LSTAT(pathBA.constData(), &buf) == 0) { m_entry.insert(KIO::UDSEntry::UDS_DEVICE_ID, buf.st_dev); m_entry.insert(KIO::UDSEntry::UDS_INODE, buf.st_ino); mode_t mode = buf.st_mode; if ((buf.st_mode & QT_STAT_MASK) == QT_STAT_LNK) { m_bLink = true; if (QT_STAT(pathBA, &buf) == 0) { mode = buf.st_mode; } else {// link pointing to nowhere (see FileProtocol::createUDSEntry() in ioslaves/file/file.cpp) mode = (QT_STAT_MASK - 1) | S_IRWXU | S_IRWXG | S_IRWXO; } } m_entry.insert(KIO::UDSEntry::UDS_SIZE, buf.st_size); m_entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, buf.st_mode & QT_STAT_MASK); // extract file type m_entry.insert(KIO::UDSEntry::UDS_ACCESS, buf.st_mode & 07777); // extract permissions m_entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, buf.st_mtime); // TODO: we could use msecs too... m_entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, buf.st_atime); #ifndef Q_OS_WIN m_entry.insert(KIO::UDSEntry::UDS_USER, KUser(buf.st_uid).loginName()); m_entry.insert(KIO::UDSEntry::UDS_GROUP, KUserGroup(buf.st_gid).name()); #endif // TODO: these can be removed, we can use UDS_FILE_TYPE and UDS_ACCESS everywhere if (m_fileMode == KFileItem::Unknown) { m_fileMode = mode & QT_STAT_MASK; // extract file type } if (m_permissions == KFileItem::Unknown) { m_permissions = mode & 07777; // extract permissions } } } } }
/*! Returns a MIME type for \a fileInfo. A valid MIME type is always returned. The default matching algorithm looks at both the file name and the file contents, if necessary. The file extension has priority over the contents, but the contents will be used if the file extension is unknown, or matches multiple MIME types. If \a fileInfo is a Unix symbolic link, the file that it refers to will be used instead. If the file doesn't match any known pattern or data, the default MIME type (application/octet-stream) is returned. When \a mode is set to MatchExtension, only the file name is used, not the file contents. The file doesn't even have to exist. If the file name doesn't match any known pattern, the default MIME type (application/octet-stream) is returned. If multiple MIME types match this file, the first one (alphabetically) is returned. When \a mode is set to MatchContent, and the file is readable, only the file contents are used to determine the MIME type. This is equivalent to calling mimeTypeForData with a QFile as input device. In all cases, the \a fileName can also include an absolute or relative path. \sa isDefault, mimeTypeForData */ QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const { DBG() << "fileInfo" << fileInfo.absoluteFilePath(); QMutexLocker locker(&d->mutex); if (fileInfo.isDir()) return d->mimeTypeForName(QLatin1String("inode/directory")); QFile file(fileInfo.absoluteFilePath()); #ifdef Q_OS_UNIX // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); QT_STATBUF statBuffer; if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { if (S_ISCHR(statBuffer.st_mode)) return d->mimeTypeForName(QLatin1String("inode/chardevice")); if (S_ISBLK(statBuffer.st_mode)) return d->mimeTypeForName(QLatin1String("inode/blockdevice")); if (S_ISFIFO(statBuffer.st_mode)) return d->mimeTypeForName(QLatin1String("inode/fifo")); if (S_ISSOCK(statBuffer.st_mode)) return d->mimeTypeForName(QLatin1String("inode/socket")); } #endif int priority = 0; switch (mode) { case MatchDefault: file.open(QIODevice::ReadOnly); // isOpen() will be tested by method below return d->mimeTypeForNameAndData(fileInfo.absoluteFilePath(), &file, &priority); case MatchExtension: locker.unlock(); return mimeTypeForFile(fileInfo.absoluteFilePath(), mode); case MatchContent: if (file.open(QIODevice::ReadOnly)) { locker.unlock(); return mimeTypeForData(&file); } else { return d->mimeTypeForName(d->defaultMimeType()); } default: Q_ASSERT(false); } return d->mimeTypeForName(d->defaultMimeType()); }
QT_BEGIN_NAMESPACE #ifdef Q_WS_QWS #error qvfb must be compiled with the Qt for X11 package #endif // Get the name of the directory where Qt for Embedded Linux temporary data should // live. static QString qws_dataDir(int qws_display_id) { static QString result; if (!result.isEmpty()) return result; result = QT_VFB_DATADIR(qws_display_id); QByteArray dataDir = result.toLocal8Bit(); #if defined(Q_OS_INTEGRITY) /* ensure filesystem is ready before starting requests */ WaitForFileSystemInitialization(); #endif if (QT_MKDIR(dataDir, 0700)) { if (errno != EEXIST) { qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData()); } } QT_STATBUF buf; if (QT_LSTAT(dataDir, &buf)) qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData()); if (!S_ISDIR(buf.st_mode)) qFatal("%s is not a directory", dataDir.constData()); #if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_QNX) if (buf.st_uid != getuid()) qFatal("Qt for Embedded Linux data directory is not owned by user %uh", getuid()); if ((buf.st_mode & 0677) != 0600) qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData()); #endif result.append(QLatin1Char('/')); return result; }
void KFileItemPrivate::init() { m_access.clear(); // metaInfo = KFileMetaInfo(); // determine mode and/or permissions if unknown // TODO: delay this until requested if (m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown) { mode_t mode = 0; if (m_url.isLocalFile()) { /* directories may not have a slash at the end if * we want to stat() them; it requires that we * change into it .. which may not be allowed * stat("/is/unaccessible") -> rwx------ * stat("/is/unaccessible/") -> EPERM H.Z. * This is the reason for the StripTrailingSlash */ QT_STATBUF buf; const QString path = m_url.adjusted(QUrl::StripTrailingSlash).toLocalFile(); const QByteArray pathBA = QFile::encodeName(path); if (QT_LSTAT(pathBA.constData(), &buf) == 0) { mode = buf.st_mode; if ((buf.st_mode & QT_STAT_MASK) == QT_STAT_LNK) { m_bLink = true; if (QT_STAT(pathBA, &buf) == 0) { mode = buf.st_mode; } else {// link pointing to nowhere (see FileProtocol::createUDSEntry() in kioslave/file/file.cpp) mode = (QT_STAT_MASK - 1) | S_IRWXU | S_IRWXG | S_IRWXO; } } // While we're at it, store the times setTime(KFileItem::ModificationTime, buf.st_mtime); setTime(KFileItem::AccessTime, buf.st_atime); if (m_fileMode == KFileItem::Unknown) { m_fileMode = mode & QT_STAT_MASK; // extract file type } if (m_permissions == KFileItem::Unknown) { m_permissions = mode & 07777; // extract permissions } } } } }
bool SynchronizerDirList::load(const QString &urlIn, bool wait) { if (busy) return false; currentUrl = urlIn; QUrl url = QUrl::fromUserInput(urlIn, QString(), QUrl::AssumeLocalFile); QHashIterator< QString, vfile *> lit(*this); while (lit.hasNext()) delete lit.next().value(); clear(); if (fileIterator) { delete fileIterator; fileIterator = 0; } if (url.isLocalFile()) { QString path = url.adjusted(QUrl::StripTrailingSlash).path(); QT_DIR* dir = QT_OPENDIR(path.toLocal8Bit()); if (!dir) { KMessageBox::error(parentWidget, i18n("Cannot open the %1 directory.", path), i18n("Error")); emit finished(result = false); return false; } QT_DIRENT* dirEnt; QString name; while ((dirEnt = QT_READDIR(dir)) != NULL) { name = QString::fromLocal8Bit(dirEnt->d_name); if (name == "." || name == "..") continue; if (ignoreHidden && name.startsWith('.')) continue; QString fullName = path + '/' + name; QT_STATBUF stat_p; QT_LSTAT(fullName.toLocal8Bit(), &stat_p); QString perm = KRpermHandler::mode2QString(stat_p.st_mode); bool symLink = S_ISLNK(stat_p.st_mode); QString symlinkDest; bool brokenLink = false; if (symLink) { // who the link is pointing to ? char symDest[256]; memset(symDest, 0, 256); int endOfName = 0; endOfName = readlink(fullName.toLocal8Bit(), symDest, 256); if (endOfName != -1) { QString absSymDest = symlinkDest = QString::fromLocal8Bit(symDest); if (!absSymDest.startsWith('/')) absSymDest = QDir::cleanPath(path + '/' + absSymDest); if (QDir(absSymDest).exists()) perm[0] = 'd'; if (!QDir(path).exists(absSymDest)) brokenLink = true; } } QString mime; QUrl fileURL = QUrl::fromLocalFile(fullName); vfile* item = new vfile(name, stat_p.st_size, perm, stat_p.st_mtime, symLink, brokenLink, stat_p.st_uid, stat_p.st_gid, mime, symlinkDest, stat_p.st_mode); item->vfile_setUrl(fileURL); insert(name, item); } QT_CLOSEDIR(dir); emit finished(result = true); return true; } else { KIO::Job *job = KIO::listDir(url, KIO::HideProgressInfo, true); connect(job, SIGNAL(entries(KIO::Job*, const KIO::UDSEntryList&)), this, SLOT(slotEntries(KIO::Job*, const KIO::UDSEntryList&))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotListResult(KJob*))); busy = true; if (!wait) return true; while (busy) qApp->processEvents(); return result; } }
//static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { #if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::BundleType) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) what |= QFileSystemMetaData::DirectoryType; } #endif #if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) \ && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (what & QFileSystemMetaData::HiddenAttribute) { // Mac OS >= 10.5: st_flags & UF_HIDDEN what |= QFileSystemMetaData::PosixStatFlags; } #endif if (what & QFileSystemMetaData::PosixStatFlags) what |= QFileSystemMetaData::PosixStatFlags; if (what & QFileSystemMetaData::ExistsAttribute) { // FIXME: Would other queries being performed provide this bit? what |= QFileSystemMetaData::PosixStatFlags; } data.entryFlags &= ~what; const char * nativeFilePath; int nativeFilePathLength; { const QByteArray &path = entry.nativeFilePath(); nativeFilePath = path.constData(); nativeFilePathLength = path.size(); Q_UNUSED(nativeFilePathLength); } bool entryExists = true; // innocent until proven otherwise QT_STATBUF statBuffer; bool statBufferValid = false; if (what & QFileSystemMetaData::LinkType) { if (QT_LSTAT(nativeFilePath, &statBuffer) == 0) { if (S_ISLNK(statBuffer.st_mode)) { data.entryFlags |= QFileSystemMetaData::LinkType; } else { statBufferValid = true; data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; } } else { entryExists = false; } data.knownFlagsMask |= QFileSystemMetaData::LinkType; } if (statBufferValid || (what & QFileSystemMetaData::PosixStatFlags)) { if (entryExists && !statBufferValid) statBufferValid = (QT_STAT(nativeFilePath, &statBuffer) == 0); if (statBufferValid) data.fillFromStatBuf(statBuffer); else { entryExists = false; data.creationTime_ = 0; data.modificationTime_ = 0; data.accessTime_ = 0; data.size_ = 0; data.userId_ = (uint) -2; data.groupId_ = (uint) -2; } // reset the mask data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags | QFileSystemMetaData::ExistsAttribute; } #if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::AliasType) { if (entryExists) { FSRef fref; if (FSPathMakeRef((const UInt8 *)nativeFilePath, &fref, NULL) == noErr) { Boolean isAlias, isFolder; if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr) { if (isAlias) data.entryFlags |= QFileSystemMetaData::AliasType; } } } data.knownFlagsMask |= QFileSystemMetaData::AliasType; } #endif if (what & QFileSystemMetaData::UserPermissions) { // calculate user permissions if (entryExists) { if (what & QFileSystemMetaData::UserReadPermission) { if (QT_ACCESS(nativeFilePath, R_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserReadPermission; } if (what & QFileSystemMetaData::UserWritePermission) { if (QT_ACCESS(nativeFilePath, W_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserWritePermission; } if (what & QFileSystemMetaData::UserExecutePermission) { if (QT_ACCESS(nativeFilePath, X_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserExecutePermission; } } data.knownFlagsMask |= (what & QFileSystemMetaData::UserPermissions); } if (what & QFileSystemMetaData::HiddenAttribute && !data.isHidden()) { QString fileName = entry.fileName(); if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) || (entryExists && _q_isMacHidden(nativeFilePath))) data.entryFlags |= QFileSystemMetaData::HiddenAttribute; data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } #if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC) if (what & QFileSystemMetaData::BundleType) { if (entryExists && data.isDirectory()) { QCFType<CFStringRef> path = CFStringCreateWithBytes(0, (const UInt8*)nativeFilePath, nativeFilePathLength, kCFStringEncodingUTF8, false); QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, true); UInt32 type, creator; if (CFBundleGetPackageInfoInDirectory(url, &type, &creator)) data.entryFlags |= QFileSystemMetaData::BundleType; } data.knownFlagsMask |= QFileSystemMetaData::BundleType; } #endif return data.hasFlags(what); }
//static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) { #if defined(Q_OS_MACX) if (what & QFileSystemMetaData::BundleType) { if (!data.hasFlags(QFileSystemMetaData::DirectoryType)) what |= QFileSystemMetaData::DirectoryType; } if (what & QFileSystemMetaData::HiddenAttribute) { // Mac OS >= 10.5: st_flags & UF_HIDDEN what |= QFileSystemMetaData::PosixStatFlags; } #endif // defined(Q_OS_MACX) if (what & QFileSystemMetaData::PosixStatFlags) what |= QFileSystemMetaData::PosixStatFlags; if (what & QFileSystemMetaData::ExistsAttribute) { // FIXME: Would other queries being performed provide this bit? what |= QFileSystemMetaData::PosixStatFlags; } data.entryFlags &= ~what; const char * nativeFilePath; int nativeFilePathLength; { const QByteArray &path = entry.nativeFilePath(); nativeFilePath = path.constData(); nativeFilePathLength = path.size(); Q_UNUSED(nativeFilePathLength); } bool entryExists = true; // innocent until proven otherwise QT_STATBUF statBuffer; bool statBufferValid = false; if (what & QFileSystemMetaData::LinkType) { if (QT_LSTAT(nativeFilePath, &statBuffer) == 0) { if (S_ISLNK(statBuffer.st_mode)) { data.entryFlags |= QFileSystemMetaData::LinkType; } else { statBufferValid = true; data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; } } else { entryExists = false; } data.knownFlagsMask |= QFileSystemMetaData::LinkType; } if (statBufferValid || (what & QFileSystemMetaData::PosixStatFlags)) { if (entryExists && !statBufferValid) statBufferValid = (QT_STAT(nativeFilePath, &statBuffer) == 0); if (statBufferValid) data.fillFromStatBuf(statBuffer); else { entryExists = false; data.creationTime_ = 0; data.modificationTime_ = 0; data.accessTime_ = 0; data.size_ = 0; data.userId_ = (uint) -2; data.groupId_ = (uint) -2; } // reset the mask data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags | QFileSystemMetaData::ExistsAttribute; } #if defined(Q_OS_MACX) if (what & QFileSystemMetaData::AliasType) { if (entryExists) { FSRef fref; if (FSPathMakeRef((const UInt8 *)nativeFilePath, &fref, NULL) == noErr) { Boolean isAlias, isFolder; if (FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr) { if (isAlias) data.entryFlags |= QFileSystemMetaData::AliasType; } } } data.knownFlagsMask |= QFileSystemMetaData::AliasType; } #endif if (what & QFileSystemMetaData::UserPermissions) { // calculate user permissions if (entryExists) { if (what & QFileSystemMetaData::UserReadPermission) { if (QT_ACCESS(nativeFilePath, R_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserReadPermission; } if (what & QFileSystemMetaData::UserWritePermission) { if (QT_ACCESS(nativeFilePath, W_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserWritePermission; } if (what & QFileSystemMetaData::UserExecutePermission) { if (QT_ACCESS(nativeFilePath, X_OK) == 0) data.entryFlags |= QFileSystemMetaData::UserExecutePermission; } } data.knownFlagsMask |= (what & QFileSystemMetaData::UserPermissions); } if (what & QFileSystemMetaData::HiddenAttribute && !data.isHidden()) { QString fileName = entry.fileName(); if ((fileName.size() > 0 && fileName.at(0) == QLatin1Char('.')) || (entryExists && _q_isMacHidden(nativeFilePath))) data.entryFlags |= QFileSystemMetaData::HiddenAttribute; data.knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; } #if defined(Q_OS_MACX) if (what & QFileSystemMetaData::BundleType) { if (entryExists && isPackage(data, entry)) data.entryFlags |= QFileSystemMetaData::BundleType; data.knownFlagsMask |= QFileSystemMetaData::BundleType; } #endif if (!entryExists) { data.clearFlags(what); return false; } return data.hasFlags(what); }
void KRSearchMod::scanLocalDir(QUrl urlToScan) { QString dir = vfs::ensureTrailingSlash(urlToScan).path(); QT_DIR* d = QT_OPENDIR(dir.toLocal8Bit()); if (!d) return ; QT_DIRENT* dirEnt; while ((dirEnt = QT_READDIR(d)) != NULL) { QString name = QString::fromLocal8Bit(dirEnt->d_name); // we don't scan the ".",".." enteries if (name == "." || name == "..") continue; QT_STATBUF stat_p; QT_LSTAT((dir + name).toLocal8Bit(), &stat_p); QUrl url = QUrl::fromLocalFile(dir + name); QString mime; if (query->searchInArchives() || !query->hasMimeType()) { QMimeDatabase db; QMimeType mt = db.mimeTypeForUrl(url); if (mt.isValid()) mime = mt.name(); } // creating a vfile object for matching with krquery vfile * vf = new vfile(name, (KIO::filesize_t)stat_p.st_size, KRpermHandler::mode2QString(stat_p.st_mode), stat_p.st_mtime, S_ISLNK(stat_p.st_mode), false/*FIXME*/, stat_p.st_uid, stat_p.st_gid, mime, "", stat_p.st_mode, -1, url); if (query->isRecursive()) { if (S_ISLNK(stat_p.st_mode) && query->followLinks()) unScannedUrls.push(QUrl::fromLocalFile(QDir(dir + name).canonicalPath())); else if (S_ISDIR(stat_p.st_mode)) unScannedUrls.push(url); } if (query->searchInArchives()) { if (KRarcHandler::arcSupported(mime)) { QUrl archiveURL = url; bool encrypted; QString realType = arcHandler.getType(encrypted, url.path(), mime); if (!encrypted) { if (realType == "tbz" || realType == "tgz" || realType == "tarz" || realType == "tar" || realType == "tlz") archiveURL.setScheme("tar"); else archiveURL.setScheme("krarc"); unScannedUrls.push(archiveURL); } } } if (query->match(vf)) { // if we got here - we got a winner results.append(dir + name); emit found(name, dir, (KIO::filesize_t) stat_p.st_size, stat_p.st_mtime, KRpermHandler::mode2QString(stat_p.st_mode), stat_p.st_uid, stat_p.st_gid, query->foundText()); } delete vf; if (timer.elapsed() >= EVENT_PROCESS_DELAY) { qApp->processEvents(); timer.start(); if (stopSearch) return; } } // clean up QT_CLOSEDIR(d); }