Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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))
            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;
}
Ejemplo n.º 4
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) {
                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;
}
Ejemplo n.º 6
0
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
                }
            }
        }
    }
}
Ejemplo n.º 7
0
/*
    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;
}
Ejemplo n.º 8
0
// 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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/*!
    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());
}
Ejemplo n.º 11
0
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
                }
            }
        }
    }
}
Ejemplo n.º 12
0
//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;
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
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();
}
Ejemplo n.º 18
0
//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);
}
Ejemplo n.º 19
0
//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);
}