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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
KArchiveDirectory *KArchive::findOrCreate(const QString &path)
{
    //qCDebug(KArchiveLog) << path;
    if (path.isEmpty() || path == QLatin1String("/") || path == QLatin1String(".")) { // root dir => found
        //qCDebug(KArchiveLog) << "returning rootdir";
        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
    const KArchiveEntry *ent = rootDir()->entry(path);
    if (ent) {
        if (ent->isDirectory())
            //qCDebug(KArchiveLog) << "found it";
        {
            const KArchiveDirectory *dir = static_cast<const KArchiveDirectory *>(ent);
            return const_cast<KArchiveDirectory *>(dir);
        } else {
            const KArchiveFile *file = static_cast<const KArchiveFile *>(ent);
            if (file->size() > 0) {
                qCWarning(KArchiveLog) << path << "is normal file, but there are file paths in the archive assuming it is a directory, bailing out";
                return nullptr;
            }

            qCDebug(KArchiveLog) << path << " is an empty file, assuming it is actually a directory and replacing";
            KArchiveEntry *myEntry = const_cast<KArchiveEntry*>(ent);
            rootDir()->removeEntry(myEntry);
            delete myEntry;
        }
    }

    // Otherwise go up and try again
    int pos = path.lastIndexOf(QLatin1Char('/'));
    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.
    }

    //qCDebug(KArchiveLog) << "found parent " << parent->name() << " adding " << dirname << " to ensure " << path;
    // Found -> add the missing piece
    KArchiveDirectory *e = new KArchiveDirectory(this, dirname, d->rootDir->permissions(),
                                                 d->rootDir->date(), d->rootDir->user(),
                                                 d->rootDir->group(), QString());
    parent->addEntry(e);
    return e; // now a directory to <path> exists
}
KArchiveDirectory * KArchiveHandler::findOrCreate( const QString & path )
{
    //qDebug() << path;
    if ( path.isEmpty() || path == QLatin1String("/") || path == QLatin1String(".") ) // root dir => found
    {
        //qDebug() << "returning rootdir";
        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
    const KArchiveEntry* ent = rootDir()->entry( path );
    if ( ent )
    {
        if ( ent->isDirectory() )
            //qDebug() << "found it";
            return (KArchiveDirectory *) ent;
        else {
            //qWarning() << "Found" << path << "but it's not a directory";
        }
    }

    // Otherwise go up and try again
    int pos = path.lastIndexOf( QLatin1Char('/') );
    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.
    }

    //qDebug() << "found parent " << parent->name() << " adding " << dirname << " to ensure " << path;
    // Found -> add the missing piece
    KArchiveDirectory * e = new KArchiveDirectory( d->archive, dirname, d->rootDir->permissions(),
                                                   d->rootDir->date(), d->rootDir->user(),
                                                   d->rootDir->group(), QString() );
    parent->addEntry( e );
    return e; // now a directory to <path> exists
}
Beispiel #5
0
bool IconThemesConfig::installThemes(const QStringList &themes, const QString &archiveName)
{
  bool everythingOk = true;
  QString localThemesDir(locateLocal("icon", "./"));

  KProgressDialog progressDiag(this, "themeinstallprogress",
                               i18n("Installing icon themes"),
                               QString::null,
                               true);
  progressDiag.setAutoClose(true);
  progressDiag.progressBar()->setTotalSteps(themes.count());
  progressDiag.show();

  KTar archive(archiveName);
  archive.open(IO_ReadOnly);
  kapp->processEvents();

  const KArchiveDirectory* rootDir = archive.directory();

  KArchiveDirectory* currentTheme;
  for (QStringList::ConstIterator it = themes.begin();
       it != themes.end();
       ++it) {
    progressDiag.setLabel(
        i18n("<qt>Installing <strong>%1</strong> theme</qt>")
        .arg(*it));
    kapp->processEvents();

    if (progressDiag.wasCancelled())
      break;

    currentTheme = dynamic_cast<KArchiveDirectory*>(
                     const_cast<KArchiveEntry*>(
                       rootDir->entry(*it)));
    if (currentTheme == NULL) {
      // we tell back that something went wrong, but try to install as much
      // as possible
      everythingOk = false;
      continue;
    }

    currentTheme->copyTo(localThemesDir + *it);
    progressDiag.progressBar()->advance(1);
  }

  archive.close();
  return everythingOk;
}
Beispiel #6
0
bool KPak::openArchive(int mode) {
	kdDebug(7000) << "openArchiving!";
	if ( mode == IO_WriteOnly )
		return true;
	if ( mode != IO_ReadOnly && mode != IO_ReadWrite )
	{
		kdWarning(7000) << "Unsupported mode " << mode << endl;
		return false;
	}
	
	QIODevice *dev = device();

	if (!dev)
		return false;

	_pakFile = new libPak(dev);
	if (!_pakFile->isValidPak()) {
		kdWarning(7000) << "Invalid file magic" << endl;
		return false;
	}

	QValueList<libPak::PakFile> files(_pakFile->getAllFiles());
	
	for ( QValueList<libPak::PakFile>::Iterator it = files.begin(); it != files.end(); ++it ) {
		QString temp((*it).filename.mid(1));
		temp.replace("\\", "/");
		int pos = temp.findRev("/");
		QString file;
		file = temp.mid(pos + 1);
		// TODO: Add position and size
		KArchiveEntry *e = new KArchiveFile(this, file, 0444, 0, /*uid*/0, /*gid*/0, /*symlink*/0, (int)(*it).offset, (*it).size);
		if (pos == -1) {
			rootDir()->addEntry(e);
		} else {
			QString path = QDir::cleanDirPath( (*it).filename.mid(1).replace("\\", "/").left(pos) );
			KArchiveDirectory *d = findOrCreate(path);
			d->addEntry(e);
		}
	}
	return true;
}
Beispiel #7
0
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;
}
Beispiel #8
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]);
    }
}
Beispiel #9
0
bool KTar::openArchive( QIODevice::OpenMode mode ) {

    if ( !(mode & QIODevice::ReadOnly) )
        return true;

    if ( !d->fillTempFile( fileName() ) )
        return false;

    // We'll use the permission and user/group of d->rootDir
    // for any directory we emulate (see findOrCreate)
    //struct stat buf;
    //stat( fileName(), &buf );

    d->dirList.clear();
    QIODevice* dev = device();

    if ( !dev )
        return false;

    // read dir information
    char buffer[ 0x200 ];
    bool ende = false;
    do
    {
        QString name;
        QString symlink;

        // Read header
        qint64 n = d->readHeader( buffer, name, symlink );
        if (n < 0) return false;
        if (n == 0x200)
        {
            bool isdir = false;

            if ( name.endsWith( QLatin1Char( '/' ) ) )
            {
                isdir = true;
                name.truncate( name.length() - 1 );
            }

            QByteArray prefix = QByteArray(buffer + 0x159, 155);
            if (prefix[0] != '\0') {
                name = (QString::fromLatin1(prefix.constData()) + QLatin1Char('/') +  name);
            }

            int pos = name.lastIndexOf( QLatin1Char('/') );
            QString nm = ( pos == -1 ) ? name : name.mid( pos + 1 );

            // read access
            buffer[ 0x6b ] = 0;
            char *dummy;
            const char* p = buffer + 0x64;
            while( *p == ' ' ) ++p;
            int access = (int)strtol( p, &dummy, 8 );

            // read user and group
            QString user = QString::fromLocal8Bit( buffer + 0x109 );
            QString group = QString::fromLocal8Bit( buffer + 0x129 );

            // read time
            buffer[ 0x93 ] = 0;
            p = buffer + 0x88;
            while( *p == ' ' ) ++p;
            uint time = (int)strtol( p, &dummy, 8 );

            // read type flag
            char typeflag = buffer[ 0x9c ];
            // '0' for files, '1' hard link, '2' symlink, '5' for directory
            // (and 'L' for longlink fileNames, 'K' for longlink symlink targets)
            // 'D' for GNU tar extension DUMPDIR, 'x' for Extended header referring
            // to the next file in the archive and 'g' for Global extended header

            if ( typeflag == '5' )
                isdir = true;

            bool isDumpDir = false;
            if ( typeflag == 'D' )
            {
                isdir = false;
                isDumpDir = true;
            }
            //qDebug() << nm << "isdir=" << isdir << "pos=" << dev->pos() << "typeflag=" << typeflag << " islink=" << ( typeflag == '1' || typeflag == '2' );

            if (typeflag == 'x' || typeflag == 'g') { // pax extended header, or pax global extended header
                // Skip it for now. TODO: implement reading of extended header, as per http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html
                (void)dev->read( buffer, 0x200 );
                continue;
            }

            if (isdir)
                access |= S_IFDIR; // f*cking broken tar files

            KArchiveEntry* e;
            if ( isdir )
            {
                //qDebug() << "directory" << nm;
                e = new KArchiveDirectory( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink );
            }
            else
            {
                // read size
                QByteArray sizeBuffer( buffer + 0x7c, 12 );
                qint64 size = sizeBuffer.trimmed().toLongLong( 0, 8 /*octal*/ );
                //qDebug() << "sizeBuffer='" << sizeBuffer << "' -> size=" << size;

                // for isDumpDir we will skip the additional info about that dirs contents
                if ( isDumpDir )
                {
                    //qDebug() << nm << "isDumpDir";
                    e = new KArchiveDirectory( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink );
                }
                else
                {

                    // Let's hack around hard links. Our classes don't support that, so make them symlinks
                    if ( typeflag == '1' )
                    {
                        //qDebug() << "Hard link, setting size to 0 instead of" << size;
                        size = 0; // no contents
                    }

                    //qDebug() << "file" << nm << "size=" << size;
                    e = new KArchiveFile( this, nm, access, KArchivePrivate::time_tToDateTime(time), user, group, symlink,
                                          dev->pos(), size );
                }

                // Skip contents + align bytes
                qint64 rest = size % 0x200;
                qint64 skip = size + (rest ? 0x200 - rest : 0);
                //qDebug() << "pos()=" << dev->pos() << "rest=" << rest << "skipping" << skip;
                if (! dev->seek( dev->pos() + skip ) ) {
                    //qWarning() << "skipping" << skip << "failed";
                }
            }

            if ( pos == -1 )
            {
                if (nm == QLatin1String(".")) { // special case
                    Q_ASSERT( isdir );
                    if (isdir) {
                        setRootDir( static_cast<KArchiveDirectory *>( e ) );
                    }
                } else {
                    rootDir()->addEntry( e );
                }
            }
            else
            {
                // In some tar files we can find dir/./file => call cleanPath
                QString path = QDir::cleanPath( name.left( pos ) );
                // Ensure container directory exists, create otherwise
                KArchiveDirectory * d = findOrCreate( path );
                d->addEntry( e );
            }
        }
        else
        {
            //qDebug("Terminating. Read %d bytes, first one is %d", n, buffer[0]);
            d->tarEnd = dev->pos() - n; // Remember end of archive
            ende = true;
        }
    } while( !ende );
    return true;
}
Beispiel #10
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;
}