bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const { QString dirName = name; if (createParentDirectories) { dirName = QDir::cleanPath(dirName); for(int oldslash = -1, slash=0; slash != -1; oldslash = slash) { slash = dirName.indexOf(QDir::separator(), oldslash+1); if (slash == -1) { if (oldslash == dirName.length()) break; slash = dirName.length(); } if (slash) { QByteArray chunk = QFile::encodeName(dirName.left(slash)); QT_STATBUF st; if (QT_STAT(chunk, &st) != -1) { if ((st.st_mode & S_IFMT) != S_IFDIR) return false; } else if (::mkdir(chunk, 0777) != 0) { return false; } } } return true; } #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s if (dirName[dirName.length() - 1] == QLatin1Char('/')) dirName = dirName.left(dirName.length() - 1); #endif return (::mkdir(QFile::encodeName(dirName), 0777) == 0); }
QString QFSFileEngine::currentPath(const QString &) { QString result; QT_STATBUF st; if (QT_STAT(".", &st) == 0) { #if defined(__GLIBC__) && !defined(PATH_MAX) char *currentName = ::get_current_dir_name(); if (currentName) { result = QFile::decodeName(QByteArray(currentName)); ::free(currentName); } #else char currentName[PATH_MAX+1]; if (::getcwd(currentName, PATH_MAX)) result = QFile::decodeName(QByteArray(currentName)); #endif #if defined(QT_DEBUG) if (result.isNull()) qWarning("QDir::currentPath: getcwd() failed"); #endif } else { #if defined(QT_DEBUG) qWarning("QDir::currentPath: stat(\".\") failed"); #endif } return result; }
QFileSystemEntry QFileSystemEngine::currentPath() { QFileSystemEntry result; QT_STATBUF st; if (QT_STAT(".", &st) == 0) { #if defined(__GLIBC__) && !defined(PATH_MAX) char *currentName = ::get_current_dir_name(); if (currentName) { result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); ::free(currentName); } #else char currentName[PATH_MAX+1]; if (::getcwd(currentName, PATH_MAX)) result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); # if defined(QT_DEBUG) if (result.isEmpty()) qWarning("QFSFileEngine::currentPath: getcwd() failed"); # endif #endif } else { # if defined(QT_DEBUG) qWarning("QFSFileEngine::currentPath: stat(\".\") failed"); # endif } return result; }
//static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { QString dirName = entry.filePath(); if (createParents) { dirName = QDir::cleanPath(dirName); for (int oldslash = -1, slash=0; slash != -1; oldslash = slash) { slash = dirName.indexOf(QDir::separator(), oldslash+1); if (slash == -1) { if (oldslash == dirName.length()) break; slash = dirName.length(); } if (slash) { QByteArray chunk = QFile::encodeName(dirName.left(slash)); QT_STATBUF st; if (QT_STAT(chunk, &st) != -1) { if ((st.st_mode & S_IFMT) != S_IFDIR) return false; } else if (QT_MKDIR(chunk, 0777) != 0) { return false; } } } return true; } #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s if (dirName.endsWith(QLatin1Char('/'))) dirName.chop(1); #endif return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0); }
QFileSystemEntry QFileSystemEngine::currentPath() { QFileSystemEntry result; QT_STATBUF st; if (QT_STAT(".", &st) == 0) { #if defined(__GLIBC__) && !defined(PATH_MAX) char *currentName = ::get_current_dir_name(); if (currentName) { result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); ::free(currentName); } #else char currentName[PATH_MAX+1]; if (::getcwd(currentName, PATH_MAX)) { #if defined(Q_OS_VXWORKS) && defined(VXWORKS_VXSIM) QByteArray dir(currentName); if (dir.indexOf(':') < dir.indexOf('/')) dir.remove(0, dir.indexOf(':')+1); qstrncpy(currentName, dir.constData(), PATH_MAX); #endif result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); } # if defined(QT_DEBUG) if (result.isEmpty()) qWarning("QFileSystemEngine::currentPath: getcwd() failed"); # endif #endif } else { # if defined(QT_DEBUG) qWarning("QFileSystemEngine::currentPath: stat(\".\") failed"); # endif } return result; }
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 } } } } }
/* Reads metadata about the Compose file. Later used to determine if the compose cache should be updated. The fileSize field will be zero on failure. */ static QComposeCacheFileHeader readFileMetadata(const QString &path) { quint64 fileSize = 0; qint64 lastModified = 0; const QByteArray pathBytes = QFile::encodeName(path); QT_STATBUF st; if (QT_STAT(pathBytes.data(), &st) == 0) { lastModified = st.st_mtime; fileSize = st.st_size; } QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified }; return info; }
// Returns empty vector on failure static QVector<QComposeTableElement> loadCache(const QComposeCacheFileHeader &composeInfo) { QVector<QComposeTableElement> vec; const QString cacheFilePath = getCacheFilePath(); QFile inputFile(cacheFilePath); if (!inputFile.open(QIODevice::ReadOnly)) return vec; QComposeCacheFileHeader cacheInfo; // use a "buffer" variable to make the line after this one more readable. char *buffer = reinterpret_cast<char*>(&cacheInfo); if (inputFile.read(buffer, sizeof cacheInfo) != sizeof cacheInfo) return vec; if (cacheInfo.fileSize == 0) return vec; // using "!=" just in case someone replaced with a backup that existed before if (cacheInfo.lastModified != composeInfo.lastModified) return vec; if (cacheInfo.cacheVersion != SupportedCacheVersion) return vec; const QByteArray pathBytes = QFile::encodeName(cacheFilePath); QT_STATBUF st; if (QT_STAT(pathBytes.data(), &st) != 0) return vec; const off_t fileSize = st.st_size; if (fileSize > 1024 * 1024 * 5) { // The cache file size is usually about 150KB, so if its size is over // say 5MB then somebody inflated the file, abort. return vec; } const off_t bufferSize = fileSize - (sizeof cacheInfo); const size_t elemSize = sizeof (struct QComposeTableElement); const int elemCount = bufferSize / elemSize; const QByteArray ba = inputFile.read(bufferSize); const char *data = ba.data(); // Since we know the number of the (many) elements and their size in // advance calling vector.reserve(..) seems reasonable. vec.reserve(elemCount); for (int i = 0; i < elemCount; i++) { const QComposeTableElement *elem = reinterpret_cast<const QComposeTableElement*>(data + (i * elemSize)); vec.push_back(*elem); } return vec; }
bool QFSFileEnginePrivate::doStat() const { if (tried_stat == 0) { QFSFileEnginePrivate *that = const_cast<QFSFileEnginePrivate*>(this); if (fh && nativeFilePath.isEmpty()) { // ### actually covers two cases: d->fh and when the file is not open that->could_stat = (QT_FSTAT(fileno(fh), &st) == 0); } else if (fd == -1) { // ### actually covers two cases: d->fh and when the file is not open that->could_stat = (QT_STAT(nativeFilePath.constData(), &st) == 0); } else { that->could_stat = (QT_FSTAT(fd, &st) == 0); } that->tried_stat = 1; } return could_stat; }
/*! 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. \a fileInfo may refer to an absolute or relative path. \sa QMimeType::isDefault(), mimeTypeForData() */ QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const { 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. // In addition we want to follow symlinks. const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); QT_STATBUF statBuffer; if (QT_STAT(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->mimeTypeForFileNameAndData(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()); }
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 } } } } }
//static bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents) { if (removeEmptyParents) { QString dirName = QDir::cleanPath(entry.filePath()); for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { QByteArray chunk = QFile::encodeName(dirName.left(slash)); QT_STATBUF st; if (QT_STAT(chunk, &st) != -1) { if ((st.st_mode & S_IFMT) != S_IFDIR) return false; if (::rmdir(chunk) != 0) return oldslash != 0; } else { return false; } slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); } return true; } return rmdir(QFile::encodeName(entry.filePath())) == 0; }
//static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { QString dirName = entry.filePath(); if (createParents) { dirName = QDir::cleanPath(dirName); for (int oldslash = -1, slash=0; slash != -1; oldslash = slash) { slash = dirName.indexOf(QDir::separator(), oldslash+1); if (slash == -1) { if (oldslash == dirName.length()) break; slash = dirName.length(); } if (slash) { const QByteArray chunk = QFile::encodeName(dirName.left(slash)); if (QT_MKDIR(chunk.constData(), 0777) != 0) { if (errno == EEXIST #if defined(Q_OS_QNX) // On QNX the QNet (VFS paths of other hosts mounted under a directory // such as /net) mountpoint returns ENOENT, despite existing. stat() // on the QNet mountpoint returns successfully and reports S_IFDIR. || errno == ENOENT #endif ) { QT_STATBUF st; if (QT_STAT(chunk.constData(), &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) continue; } return false; } } } return true; } #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s if (dirName.endsWith(QLatin1Char('/'))) dirName.chop(1); #endif return (QT_MKDIR(QFile::encodeName(dirName).constData(), 0777) == 0); }
bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const { QString dirName = name; if (recurseParentDirectories) { dirName = QDir::cleanPath(dirName); for(int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) { QByteArray chunk = QFile::encodeName(dirName.left(slash)); QT_STATBUF st; if (QT_STAT(chunk, &st) != -1) { if ((st.st_mode & S_IFMT) != S_IFDIR) return false; if (::rmdir(chunk) != 0) return oldslash != 0; } else { return false; } slash = dirName.lastIndexOf(QDir::separator(), oldslash-1); } return true; } return ::rmdir(QFile::encodeName(dirName)) == 0; }
/*! \internal */ qint64 QFSFileEnginePrivate::sizeFdFh() const { Q_Q(const QFSFileEngine); // ### Fix this function, it should not stat unless the file is closed. QT_STATBUF st; int ret = 0; const_cast<QFSFileEngine *>(q)->flush(); if (fh && nativeFilePath.isEmpty()) { // Buffered stdlib mode. // ### This should really be an ftell ret = QT_FSTAT(QT_FILENO(fh), &st); } else if (fd == -1) { // Stateless stat. ret = QT_STAT(nativeFilePath.constData(), &st); } else { // Unbuffered stdio mode. ret = QT_FSTAT(fd, &st); } if (ret == -1) return 0; return st.st_size; }
bool KIso::openArchive(QIODevice::OpenMode mode) { KISOFUNC; iso_vol_desc *desc; QString path, uid, gid; QT_STATBUF buf; int tracks[2*100], trackno = 0, i, access, c_b, c_i, c_j; KArchiveDirectory *root; struct iso_directory_record* idr; struct el_torito_boot_descriptor* bootdesc; if (mode == QIODevice::WriteOnly) return false; readParams(); d->dirList.clear(); tracks[0] = 0; if (m_startsec > 0) tracks[0] = m_startsec; //qDebug() << " m_startsec: " << m_startsec << endl; /* We'll use the permission and user/group of the 'host' file except * in Rock Ridge, where the permissions are stored on the file system */ if (QT_STAT(m_filename.toLocal8Bit(), &buf) < 0) { /* defaults, if stat fails */ memset(&buf, 0, sizeof(struct stat)); buf.st_mode = 0777; } else { /* If it's a block device, try to query the track layout (for multisession) */ if (m_startsec == -1 && S_ISBLK(buf.st_mode)) trackno = getTracks(m_filename.toLatin1(), (int*) & tracks); } uid.setNum(buf.st_uid); gid.setNum(buf.st_gid); access = buf.st_mode & ~S_IFMT; //qDebug() << "KIso::openArchive number of tracks: " << trackno << endl; if (trackno == 0) trackno = 1; for (i = 0;i < trackno;++i) { c_b = 1;c_i = 1;c_j = 1; root = rootDir(); if (trackno > 1) { path.clear(); QTextStream(&path) << "Track " << tracks[(i<<1)+1]; root = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); rootDir()->addEntry(root); } desc = ReadISO9660(&readf, tracks[i<<1], this); if (!desc) { //qDebug() << "KIso::openArchive no volume descriptors" << endl; continue; } while (desc) { switch (isonum_711(desc->data.type)) { case ISO_VD_BOOT: bootdesc = (struct el_torito_boot_descriptor*) & (desc->data); if (!memcmp(EL_TORITO_ID, bootdesc->system_id, ISODCL(8, 39))) { path = "El Torito Boot"; if (c_b > 1) path += " (" + QString::number(c_b) + ')'; dirent = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); root->addEntry(dirent); addBoot(bootdesc); c_b++; } break; case ISO_VD_PRIMARY: case ISO_VD_SUPPLEMENTARY: idr = (struct iso_directory_record*) & (((struct iso_primary_descriptor*) & desc->data)->root_directory_record); joliet = JolietLevel(&desc->data); if (joliet) { QTextStream(&path) << "Joliet level " << joliet; if (c_j > 1) path += " (" + QString::number(c_j) + ')'; } else { path = "ISO9660"; if (c_i > 1) path += " (" + QString::number(c_i) + ')'; } dirent = new KIsoDirectory(this, path, access | S_IFDIR, buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, QString()); root->addEntry(dirent); level = 0; mycallb(idr, this); if (joliet) c_j++; else c_i++; break; } desc = desc->next; } free(desc); } device()->close(); return true; }
void TimeAdjustTask::run() { if (m_cancel) return; emit signalProcessStarted(d->url); QDateTime dt = d->itemsMap.value(d->url); if (!dt.isValid()) { emit signalProcessEnded(d->url, TimeAdjustList::META_TIME_ERROR); emit signalDone(); return; } bool writeToSidecar = (MetaEngineSettings::instance()->settings() .metadataWritingMode != DMetadata::WRITE_TO_FILE_ONLY); bool metadataChanged = d->settings.updEXIFModDate || d->settings.updEXIFOriDate || d->settings.updEXIFDigDate || d->settings.updEXIFThmDate || d->settings.updIPTCDate || d->settings.updXMPVideo || d->settings.updXMPDate; int status = TimeAdjustList::NOPROCESS_ERROR; if (metadataChanged) { bool ret = true; DMetadata meta; ret &= meta.load(d->url.toLocalFile()); if (ret) { QString exifDateTimeFormat = QLatin1String("yyyy:MM:dd hh:mm:ss"); QString xmpDateTimeFormat = QLatin1String("yyyy:MM:ddThh:mm:ss"); if (writeToSidecar || meta.canWriteExif(d->url.toLocalFile())) { if (d->settings.updEXIFModDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Image.DateTime").isEmpty()) { ret &= meta.setExifTagString("Exif.Image.DateTime", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFOriDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Photo.DateTimeOriginal").isEmpty()) { ret &= meta.setExifTagString("Exif.Photo.DateTimeOriginal", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFDigDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Photo.DateTimeDigitized").isEmpty()) { ret &= meta.setExifTagString("Exif.Photo.DateTimeDigitized", dt.toString(exifDateTimeFormat)); } } if (d->settings.updEXIFThmDate) { if (!d->settings.updIfAvailable || !meta.getExifTagString("Exif.Image.PreviewDateTime").isEmpty()) { ret &= meta.setExifTagString("Exif.Image.PreviewDateTime", dt.toString(exifDateTimeFormat)); } } } else if (d->settings.updEXIFModDate || d->settings.updEXIFOriDate || d->settings.updEXIFDigDate || d->settings.updEXIFThmDate) { ret = false; } if (d->settings.updIPTCDate) { if (writeToSidecar || meta.canWriteIptc(d->url.toLocalFile())) { if (!d->settings.updIfAvailable || !meta.getIptcTagString("Iptc.Application2.DateCreated").isEmpty()) { ret &= meta.setIptcTagString("Iptc.Application2.DateCreated", dt.date().toString(Qt::ISODate)); } if (!d->settings.updIfAvailable || !meta.getIptcTagString("Iptc.Application2.TimeCreated").isEmpty()) { ret &= meta.setIptcTagString("Iptc.Application2.TimeCreated", dt.time().toString(Qt::ISODate)); } } else { ret = false; } } if (d->settings.updXMPDate) { if (writeToSidecar || (meta.supportXmp() && meta.canWriteXmp(d->url.toLocalFile()))) { if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.exif.DateTimeOriginal").isEmpty()) { ret &= meta.setXmpTagString("Xmp.exif.DateTimeOriginal", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.photoshop.DateCreated").isEmpty()) { ret &= meta.setXmpTagString("Xmp.photoshop.DateCreated", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.tiff.DateTime").isEmpty()) { ret &= meta.setXmpTagString("Xmp.tiff.DateTime", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.CreateDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.CreateDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.MetadataDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.MetadataDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.xmp.ModifyDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.xmp.ModifyDate", dt.toString(xmpDateTimeFormat)); } } else { ret = false; } } if (d->settings.updXMPVideo) { if (writeToSidecar || (meta.supportXmp() && meta.canWriteXmp(d->url.toLocalFile()))) { if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateTimeOriginal").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateTimeOriginal", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateTimeDigitized").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateTimeDigitized", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.ModificationDate").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.ModificationDate", dt.toString(xmpDateTimeFormat)); } if (!d->settings.updIfAvailable || !meta.getXmpTagString("Xmp.video.DateUTC").isEmpty()) { ret &= meta.setXmpTagString("Xmp.video.DateUTC", dt.toUTC().toString(xmpDateTimeFormat)); } } else { ret = false; } } ret &= meta.save(d->url.toLocalFile()); if (!ret) { qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to update metadata in file " << d->url.fileName(); } } else { qCDebug(DIGIKAM_DPLUGIN_GENERIC_LOG) << "Failed to load metadata from file " << d->url.fileName(); } if (!ret) { status |= TimeAdjustList::META_TIME_ERROR; } } if (d->settings.updFileModDate) { // Since QFileInfo does not support timestamp updates, // we have to use the utime() system call. int modtime; QDateTime unixDate; unixDate.setDate(QDate(1970, 1, 1)); unixDate.setTime(QTime(0, 0, 0, 0)); if (dt < unixDate) modtime = -(dt.secsTo(unixDate) + (60 * 60)); else modtime = dt.toTime_t(); struct utimbuf ut; ut.modtime = modtime; ut.actime = QDateTime::currentDateTime().toTime_t(); if (::utime(QFile::encodeName(d->url.toLocalFile()).constData(), &ut) != 0) { status |= TimeAdjustList::FILE_TIME_ERROR; } } if (writeToSidecar && DMetadata::hasSidecar(d->url.toLocalFile())) { QT_STATBUF st; if (QT_STAT(QFile::encodeName(d->url.toLocalFile()).constData(), &st) == 0) { struct utimbuf ut; ut.modtime = st.st_mtime; ut.actime = st.st_atime; if (::utime(QFile::encodeName(DMetadata::sidecarPath(d->url.toLocalFile())).constData(), &ut) != 0) { status |= TimeAdjustList::FILE_TIME_ERROR; } } } if (status == TimeAdjustList::NOPROCESS_ERROR) { emit signalDateTimeForUrl(d->url, dt, d->settings.updFileModDate); } emit signalProcessEnded(d->url, status); emit signalDone(); }
//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); }