예제 #1
0
void KArchiveDirectory::copyTo(const QString &dest, bool recursiveCopy) const
{
    QDir root;

    PosSortedPtrList fileList;
    QMap< int, QString > fileToDir;

    QStringList::Iterator it;

    // placeholders for iterated items
    KArchiveDirectory *curDir;
    QString curDirName;

    QStringList dirEntries;
    KArchiveEntry *curEntry;
    KArchiveFile *curFile;


    QPtrStack< KArchiveDirectory > dirStack;
    QValueStack< QString > dirNameStack;

    dirStack.push(this);     // init stack at current directory
    dirNameStack.push(dest); // ... with given path
    do
    {
        curDir = dirStack.pop();
        curDirName = dirNameStack.pop();
        root.mkdir(curDirName);

        dirEntries = curDir->entries();
        for(it = dirEntries.begin(); it != dirEntries.end(); ++it)
        {
            curEntry = curDir->entry(*it);
            if(!curEntry->symlink().isEmpty())
            {
                const QString linkName = curDirName + '/' + curEntry->name();
                kdDebug() << "symlink(" << curEntry->symlink() << ',' << linkName << ')';

                if(!::symlink(curEntry->symlink().local8Bit(), linkName.local8Bit()))
                {
                    kdDebug() << "symlink(" << curEntry->symlink() << ',' << linkName << ") failed:" << strerror(errno);
                }
            }
            else
            {
                if(curEntry->isFile())
                {
                    curFile = dynamic_cast< KArchiveFile * >(curEntry);
                    if(curFile)
                    {
                        fileList.append(curFile);
                        fileToDir.insert(curFile->position(), curDirName);
                    }
                }

                if(curEntry->isDirectory())
                    if(recursiveCopy)
                    {
                        KArchiveDirectory *ad = dynamic_cast< KArchiveDirectory * >(curEntry);
                        if(ad)
                        {
                            dirStack.push(ad);
                            dirNameStack.push(curDirName + "/" + curEntry->name());
                        }
                    }
            }
        }
    } while(!dirStack.isEmpty());

    fileList.sort(); // sort on m_pos, so we have a linear access

    KArchiveFile *f;
    for(f = fileList.first(); f; f = fileList.next())
    {
        int pos = f->position();
        f->copyTo(fileToDir[pos]);
    }
}