QStringList IconThemesConfig::findThemeDirs(const QString &archiveName) { QStringList foundThemes; KTar archive(archiveName); archive.open(IO_ReadOnly); const KArchiveDirectory* themeDir = archive.directory(); KArchiveEntry* possibleDir = 0L; KArchiveDirectory* subDir = 0L; // iterate all the dirs looking for an index.theme or index.desktop file QStringList entries = themeDir->entries(); for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { possibleDir = const_cast<KArchiveEntry*>(themeDir->entry(*it)); if (possibleDir->isDirectory()) { subDir = dynamic_cast<KArchiveDirectory*>( possibleDir ); if (subDir && (subDir->entry("index.theme") != NULL || subDir->entry("index.desktop") != NULL)) foundThemes.append(subDir->name()); } } archive.close(); return foundThemes; }
BundleInstaller::BundleStatus EmoticonSetInstaller::validate() { kDebug(); KArchiveEntry *currentEntry = 0L; KArchiveDirectory* currentDir = 0L; if(m_archive == 0) exit(1); m_archive->fileName(); m_archive->directory(); const KArchiveDirectory* rootDir = m_archive->directory(); const QStringList entries = rootDir->entries(); // Will be reused later. QStringList::ConstIterator entriesIt; for (entriesIt = entries.begin(); entriesIt != entries.end(); ++entriesIt) { currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*entriesIt)); kDebug() << "Current entry name: " << currentEntry->name(); if (currentEntry->isDirectory()) { currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry); if (currentDir) { if (currentDir->entry(QString::fromUtf8("Emoticons.plist"))) { kDebug() << "Emoticons.plist found"; QString currentItem = currentEntry->name(); if(m_bundleName.isEmpty() && currentItem.endsWith(QLatin1String(".AdiumEmoticonset"))) { m_bundleName = currentItem.remove(QLatin1String(".AdiumEmoticonset")); } return BundleValid; } } } } return BundleNotValid; }
KArchiveDirectory *KArchive::findOrCreate(const QString &path) { // kdDebug() << "KArchive::findOrCreate " << path << endl; if(path.isEmpty() || path == "/" || path == ".") // root dir => found { // kdDebug() << "KArchive::findOrCreate returning rootdir" << endl; return rootDir(); } // Important note : for tar files containing absolute paths // (i.e. beginning with "/"), this means the leading "/" will // be removed (no KDirectory for it), which is exactly the way // the "tar" program works (though it displays a warning about it) // See also KArchiveDirectory::entry(). // Already created ? => found KArchiveEntry *ent = rootDir()->entry(path); if(ent) { if(ent->isDirectory()) // kdDebug() << "KArchive::findOrCreate found it" << endl; return (KArchiveDirectory *)ent; else kdWarning() << "Found " << path << " but it's not a directory" << endl; } // Otherwise go up and try again int pos = path.findRev('/'); KArchiveDirectory *parent; QString dirname; if(pos == -1) // no more slash => create in root dir { parent = rootDir(); dirname = path; } else { QString left = path.left(pos); dirname = path.mid(pos + 1); parent = findOrCreate(left); // recursive call... until we find an existing dir. } // kdDebug() << "KTar : found parent " << parent->name() << " adding " << dirname << " to ensure " << path << endl; // Found -> add the missing piece KArchiveDirectory *e = new KArchiveDirectory(this, dirname, d->rootDir->permissions(), d->rootDir->date(), d->rootDir->user(), d->rootDir->group(), QString::null); parent->addEntry(e); return e; // now a directory to <path> exists }
/** * This function recreate a zip in dest with all files from src * except meta.xml */ bool copyZipToZip( const KZip * src, KZip * dest) { KArchiveDirectory * src_dir; KArchiveFile * input_file; QPtrStack<KArchiveDirectory> src_dirStack ; QStringList dirEntries; QStringList curDirName; QStringList::Iterator it; KArchiveEntry* curEntry; QString filename = QString::null; src_dirStack.push ( src->directory() ); do { src_dir = src_dirStack.pop(); curDirName.append(src_dir->name()); dirEntries = src_dir->entries(); /* We now iterate over all entries and create entries in dest */ for ( it = dirEntries.begin(); it != dirEntries.end(); ++it ) { if ( *it == metafile ) continue; curEntry = src_dir->entry( *it ); if (curEntry->isFile()) { input_file = dynamic_cast<KArchiveFile*>( curEntry ); QByteArray b = input_file->data(); if (curDirName.isEmpty() || src_dir->name()=="/"){ filename = *it; } else { filename = curDirName.join("/") + "/" + *it; } dest->writeFile(filename , QString::null, QString::null, b.count(), b.data() ); } else if (curEntry->isDirectory()) { src_dirStack.push( dynamic_cast<KArchiveDirectory*>( curEntry ) ); } else { kdDebug(7034) << *it << " is a unknown type. Aborting." << endl; return false; } } curDirName.pop_back(); } while ( ! src_dirStack.isEmpty() ); return true; }
KArchiveEntry *KArchiveDirectory::entry(QString name) // not "const QString & name" since we want a local copy // (to remove leading slash if any) { int pos = name.find('/'); if(pos == 0) // ouch absolute path (see also KArchive::findOrCreate) { if(name.length() > 1) { name = name.mid(1); // remove leading slash pos = name.find('/'); // look again } else // "/" return this; } // trailing slash ? -> remove if(pos != -1 && pos == (int)name.length() - 1) { name = name.left(pos); pos = name.find('/'); // look again } if(pos != -1) { QString left = name.left(pos); QString right = name.mid(pos + 1); // kdDebug() << "KArchiveDirectory::entry left=" << left << " right=" << right << endl; KArchiveEntry *e = m_entries[left]; if(!e || !e->isDirectory()) return 0; return ((KArchiveDirectory *)e)->entry(right); } return m_entries[name]; }
QStringList KEmoticons::installTheme(const QString &archiveName) { QStringList foundThemes; KArchiveEntry *currentEntry = 0L; KArchiveDirectory* currentDir = 0L; KArchive *archive = 0L; QString localThemesDir(KStandardDirs::locateLocal("emoticons", QString())); if (localThemesDir.isEmpty()) { kError() << "Could not find a suitable place in which to install the emoticon theme"; return QStringList(); } const QString currentBundleMimeType = KMimeType::findByPath(archiveName, 0, false)->name(); if (currentBundleMimeType == "application/zip" || currentBundleMimeType == "application/x-zip" || currentBundleMimeType == "application/x-zip-compressed") { archive = new KZip(archiveName); } else if (currentBundleMimeType == "application/x-compressed-tar" || currentBundleMimeType == "application/x-bzip-compressed-tar" || currentBundleMimeType == "application/x-lzma-compressed-tar" || currentBundleMimeType == "application/x-xz-compressed-tar" || currentBundleMimeType == "application/x-gzip" || currentBundleMimeType == "application/x-bzip" || currentBundleMimeType == "application/x-lzma" || currentBundleMimeType == "application/x-xz") { archive = new KTar(archiveName); } else if (archiveName.endsWith(QLatin1String("jisp")) || archiveName.endsWith(QLatin1String("zip"))) { archive = new KZip(archiveName); } else { archive = new KTar(archiveName); } if (!archive || !archive->open(QIODevice::ReadOnly)) { kError() << "Could not open" << archiveName << "for unpacking"; delete archive; return QStringList(); } const KArchiveDirectory* rootDir = archive->directory(); // iterate all the dirs looking for an emoticons.xml file const QStringList entries = rootDir->entries(); for (QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) { currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*it)); if (currentEntry->isDirectory()) { currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry); for (int i = 0; i < d->m_loaded.size(); ++i) { QString fName = d->m_loaded.at(i)->property("X-KDE-EmoticonsFileName").toString(); if (currentDir && currentDir->entry(fName) != NULL) { foundThemes.append(currentDir->name()); } } } } if (foundThemes.isEmpty()) { kError() << "The file" << archiveName << "is not a valid emoticon theme archive"; archive->close(); delete archive; return QStringList(); } for (int themeIndex = 0; themeIndex < foundThemes.size(); ++themeIndex) { const QString &theme = foundThemes[themeIndex]; currentEntry = const_cast<KArchiveEntry *>(rootDir->entry(theme)); if (currentEntry == 0) { kDebug() << "couldn't get next archive entry"; continue; } if (currentEntry->isDirectory()) { currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry); if (currentDir == 0) { kDebug() << "couldn't cast archive entry to KArchiveDirectory"; continue; } currentDir->copyTo(localThemesDir + theme); } } archive->close(); delete archive; return foundThemes; }
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]); } }