Esempio n. 1
0
bool KArchive::addLocalFile( const QString& fileName, const QString& destName )
{
    QFileInfo fileInfo( fileName );
    if ( !fileInfo.isFile() && !fileInfo.isSymLink() )
    {
        kWarning() << fileName << "doesn't exist or is not a regular file.";
        return false;
    }

    KDE_struct_stat fi;
    if (KDE::lstat(fileName,&fi) == -1) {
        kWarning() << "stat'ing" << fileName
        	<< "failed:" << strerror(errno);
        return false;
    }

    if (fileInfo.isSymLink()) {
        QString symLinkTarget;
        // Do NOT use fileInfo.readLink() for unix symlinks!
        // It returns the -full- path to the target, while we want the target string "as is".
#if defined(Q_OS_UNIX) && !defined(Q_OS_OS2EMX)
        const QByteArray encodedFileName = QFile::encodeName(fileName);
        QByteArray s;
#if defined(PATH_MAX)
        s.resize(PATH_MAX+1);
#else
        int path_max = pathconf(encodedFileName.data(), _PC_PATH_MAX);
        if (path_max <= 0) {
            path_max = 4096;
        }
        s.resize(path_max);
#endif
        int len = readlink(encodedFileName.data(), s.data(), s.size() - 1);
        if ( len >= 0 ) {
            s[len] = '\0';
            symLinkTarget = QFile::decodeName(s);
        }
#endif
        if (symLinkTarget.isEmpty()) // Mac or Windows
            symLinkTarget = fileInfo.symLinkTarget();
        return writeSymLink(destName, symLinkTarget, fileInfo.owner(),
                            fileInfo.group(), fi.st_mode, fi.st_atime, fi.st_mtime,
                            fi.st_ctime);
    }/*end if*/

    qint64 size = fileInfo.size();

    // the file must be opened before prepareWriting is called, otherwise
    // if the opening fails, no content will follow the already written
    // header and the tar file is effectively f*cked up
    QFile file( fileName );
    if ( !file.open( QIODevice::ReadOnly ) )
    {
        kWarning() << "couldn't open file " << fileName;
        return false;
    }

    if ( !prepareWriting( destName, fileInfo.owner(), fileInfo.group(), size,
    		fi.st_mode, fi.st_atime, fi.st_mtime, fi.st_ctime ) )
    {
        kWarning() << " prepareWriting" << destName << "failed";
        return false;
    }

    // Read and write data in chunks to minimize memory usage
    QByteArray array;
    array.resize( int( qMin( qint64( 1024 * 1024 ), size ) ) );
    qint64 n;
    qint64 total = 0;
    while ( ( n = file.read( array.data(), array.size() ) ) > 0 )
    {
        if ( !writeData( array.data(), n ) )
        {
            kWarning() << "writeData failed";
            return false;
        }
        total += n;
    }
    Q_ASSERT( total == size );

    if ( !finishWriting( size ) )
    {
        kWarning() << "finishWriting failed";
        return false;
    }
    return true;
}
Esempio n. 2
0
bool KArchive::addLocalFile(const QString &fileName, const QString &destName)
{
    QFileInfo fileInfo(fileName);
    if(!fileInfo.isFile() && !fileInfo.isSymLink())
    {
        kdWarning() << "KArchive::addLocalFile " << fileName << " doesn't exist or is not a regular file." << endl;
        return false;
    }

    KDE_struct_stat fi;
    if(KDE_lstat(QFile::encodeName(fileName), &fi) == -1)
    {
        kdWarning() << "KArchive::addLocalFile stating " << fileName << " failed: " << strerror(errno) << endl;
        return false;
    }

    if(fileInfo.isSymLink())
    {
        return writeSymLink(destName, fileInfo.readLink(), fileInfo.owner(), fileInfo.group(), fi.st_mode, fi.st_atime, fi.st_mtime, fi.st_ctime);
    } /*end if*/

    uint size = fileInfo.size();

    // the file must be opened before prepareWriting is called, otherwise
    // if the opening fails, no content will follow the already written
    // header and the tar file is effectively f*cked up
    QFile file(fileName);
    if(!file.open(IO_ReadOnly))
    {
        kdWarning() << "KArchive::addLocalFile couldn't open file " << fileName << endl;
        return false;
    }

    if(!prepareWriting(destName, fileInfo.owner(), fileInfo.group(), size, fi.st_mode, fi.st_atime, fi.st_mtime, fi.st_ctime))
    {
        kdWarning() << "KArchive::addLocalFile prepareWriting " << destName << " failed" << endl;
        return false;
    }

    // Read and write data in chunks to minimize memory usage
    QByteArray array(8 * 1024);
    int n;
    uint total = 0;
    while((n = file.readBlock(array.data(), array.size())) > 0)
    {
        if(!writeData(array.data(), n))
        {
            kdWarning() << "KArchive::addLocalFile writeData failed" << endl;
            return false;
        }
        total += n;
    }
    Q_ASSERT(total == size);

    if(!doneWriting(size))
    {
        kdWarning() << "KArchive::addLocalFile doneWriting failed" << endl;
        return false;
    }
    return true;
}
Esempio n. 3
0
bool KArchive::addLocalFile(const QString &fileName, const QString &destName)
{
    QFileInfo fileInfo(fileName);
    if (!fileInfo.isFile() && !fileInfo.isSymLink()) {
        setErrorString(
            tr("%1 doesn't exist or is not a regular file.")
            .arg(fileName));
        return false;
    }

#if defined(Q_OS_UNIX)
#define STAT_METHOD QT_LSTAT
#else
#define STAT_METHOD QT_STAT
#endif
    QT_STATBUF fi;
    if (STAT_METHOD(QFile::encodeName(fileName).constData(), &fi) == -1) {
        setErrorString(
            tr("Failed accessing the file %1 for adding to the archive. The error was: %2")
            .arg(fileName)
            .arg(QLatin1Literal{strerror(errno)}));
        return false;
    }

    if (fileInfo.isSymLink()) {
        QString symLinkTarget;
        // Do NOT use fileInfo.readLink() for unix symlinks!
        // It returns the -full- path to the target, while we want the target string "as is".
#if defined(Q_OS_UNIX) && !defined(Q_OS_OS2EMX)
        const QByteArray encodedFileName = QFile::encodeName(fileName);
        QByteArray s;
#if defined(PATH_MAX)
        s.resize(PATH_MAX + 1);
#else
        int path_max = pathconf(encodedFileName.data(), _PC_PATH_MAX);
        if (path_max <= 0) {
            path_max = 4096;
        }
        s.resize(path_max);
#endif
        int len = readlink(encodedFileName.data(), s.data(), s.size() - 1);
        if (len >= 0) {
            s[len] = '\0';
            symLinkTarget = QFile::decodeName(s.constData());
        }
#endif
        if (symLinkTarget.isEmpty()) { // Mac or Windows
            symLinkTarget = fileInfo.symLinkTarget();
        }
        return writeSymLink(destName, symLinkTarget, fileInfo.owner(),
                            fileInfo.group(), fi.st_mode, fileInfo.lastRead(), fileInfo.lastModified(),
                            fileInfo.created());
    }/*end if*/

    qint64 size = fileInfo.size();

    // the file must be opened before prepareWriting is called, otherwise
    // if the opening fails, no content will follow the already written
    // header and the tar file is effectively f*cked up
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) {
        setErrorString(
            tr("Couldn't open file %1: %2")
            .arg(fileName)
            .arg(file.errorString()));
        return false;
    }

    if (!prepareWriting(destName, fileInfo.owner(), fileInfo.group(), size,
                        fi.st_mode, fileInfo.lastRead(), fileInfo.lastModified(), fileInfo.created())) {
        //qCWarning(KArchiveLog) << " prepareWriting" << destName << "failed";
        return false;
    }

    // Read and write data in chunks to minimize memory usage
    QByteArray array;
    array.resize(int(qMin(qint64(1024 * 1024), size)));
    qint64 n;
    qint64 total = 0;
    while ((n = file.read(array.data(), array.size())) > 0) {
        if (!writeData(array.data(), n)) {
            //qCWarning(KArchiveLog) << "writeData failed";
            return false;
        }
        total += n;
    }
    Q_ASSERT(total == size);

    if (!finishWriting(size)) {
        //qCWarning(KArchiveLog) << "finishWriting failed";
        return false;
    }
    return true;
}