Commit cbb3aadc authored by Raphael Kubo da Costa's avatar Raphael Kubo da Costa
Browse files

Generalize LibGzipInterface to make it support bz2 and lzma files by

making it use KFilterDev.
liblzmaplugin has been removed due to this.
Moved checks for the necessary libraries for gz/bz2/lzma support to
libsinglefileplugin/CMakeLists.txt.

BUG: 188213
BUG: 164795

svn path=/trunk/KDE/kdeutils/ark/; revision=957330
parent b9506834
macro_optional_find_package(LibArchive)
macro_optional_find_package(LibLZMA)
macro_optional_find_package(LibZip)
macro_optional_find_package(ZLIB)
macro_log_feature(LIBARCHIVE_FOUND "LibArchive" "A library for dealing with a wide variety of archive file formats" "http://people.freebsd.org/~kientzle/libarchive/" FALSE "" "Required for among others tar, tar.gz, tar.bz2 formats in Ark. Make sure it is compiled with gzip support.")
macro_log_feature(LIBLZMA_FOUND "LibLZMA" "Liblzma is used for the .xz and .lzma formats" "http://tukaani.org/xz/" FALSE "" "Required for the .xz and .lzma format support in Ark")
macro_log_feature(LIBZIP_FOUND "LibZip" "A library for reading, creating, and modifying ZIP archives" "http://www.nih.at/libzip" FALSE "" "Required for building ZIP support into Ark.")
macro_log_feature(ZLIB_FOUND "zlib" "zlib is used for the .gz format" "http://www.zlib.net" FALSE "" "Required for the .gz format support in Ark")
if (LIBARCHIVE_FOUND)
add_subdirectory( libarchive )
endif (LIBARCHIVE_FOUND)
if (LIBLZMA_FOUND)
add_subdirectory( liblzmaplugin )
endif (LIBLZMA_FOUND)
if (LIBZIP_FOUND)
add_subdirectory( libzipplugin )
endif (LIBZIP_FOUND)
if (ZLIB_FOUND)
add_subdirectory( libgzplugin )
endif (ZLIB_FOUND)
#add_subdirectory( 7zipplugin )
add_subdirectory( clirarplugin )
add_subdirectory( cli7zplugin )
add_subdirectory( libsinglefileplugin )
add_subdirectory( unace )
if(NOT WIN32)
......
include_directories( ${ZLIB_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_BINARY_DIR}/../..
)
########### next target ###############
set(kerfuffle_libgz_SRCS gzplugin.cpp)
kde4_add_plugin(kerfuffle_libgz ${kerfuffle_libgz_SRCS})
target_link_libraries(kerfuffle_libgz ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${ZLIB_LIBRARIES} kerfuffle )
install(TARGETS kerfuffle_libgz DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES kerfuffle_libgz.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
include_directories( ${LIBLZMA_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_BINARY_DIR}/../..
)
########### next target ###############
set(kerfuffle_liblzma_SRCS lzmaplugin.cpp)
kde4_add_plugin(kerfuffle_liblzma ${kerfuffle_liblzma_SRCS})
target_link_libraries(kerfuffle_liblzma ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} ${LIBLZMA_LIBRARIES} kerfuffle )
install(TARGETS kerfuffle_liblzma DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES kerfuffle_liblzma.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
/***************************************************************************
* Copyright (C) 2009 by Wang Hoi <zealot.hoi@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "kerfuffle/archiveinterface.h"
#include "kerfuffle/archivefactory.h"
#include <lzma.h>
#include <stdio.h>
#include <errno.h>
#include <KLocale>
#include <KDebug>
#include <QDateTime>
#include <QString>
#include <QFileInfo>
#include <QByteArray>
#include <QFile>
#include <QDir>
using namespace Kerfuffle;
class LibLZMAInterface: public ReadOnlyArchiveInterface
{
Q_OBJECT
public:
LibLZMAInterface( const QString & filename, QObject *parent )
: ReadOnlyArchiveInterface( filename, parent )
{
}
~LibLZMAInterface()
{
kDebug( 1601 ) ;
}
QString uncompressedFilename()
{
QString fn = QFileInfo(filename()).fileName();
if (fn.toUpper().endsWith(".XZ")) {
fn.chop(3);
return fn;
}
if (fn.toUpper().endsWith(".LZMA")) {
fn.chop(5);
return fn;
}
//we need to return something...
return filename() + ".xzUncompressed";
}
bool list()
{
kDebug( 1601 );
QString file = uncompressedFilename();
Q_ASSERT(!file.isEmpty());
ArchiveEntry e;
e[ FileName ] = file;
e[ InternalID ] = file;
//e[ Size ] = static_cast<qulonglong>( stat.size );
//e[ Timestamp ] = QDateTime::fromTime_t( stat.mtime );
//e[ CompressedSize ] = static_cast<qulonglong>( stat.comp_size );
entry( e );
return true;
}
bool lzma_uncompress(lzma_stream *strm, FILE *file, FILE *out_file)
{
lzma_ret ret;
// use 100 Mib as the default limit.
quint64 memlimit = (100U << 23);
// Initialize the decoder
ret = lzma_auto_decoder(strm, memlimit, 0);
// The only reasonable error here is LZMA_MEM_ERROR.
// FIXME: Maybe also LZMA_MEMLIMIT_ERROR in future?
if (ret != LZMA_OK) {
if (ret == LZMA_MEM_ERROR)
error(QString(strerror(ENOMEM)));
else
error("Internal program error (bug)");
return false;
}
// Input and output buffers
uint8_t in_buf[BUFSIZ];
uint8_t out_buf[BUFSIZ];
strm->avail_in = 0;
strm->next_out = out_buf;
strm->avail_out = BUFSIZ;
lzma_action action = LZMA_RUN;
while (true) {
if (strm->avail_in == 0) {
strm->next_in = in_buf;
strm->avail_in = fread(in_buf, 1, BUFSIZ, file);
if (ferror(file)) {
// POSIX says that fread() sets errno if
// an error occurred. ferror() doesn't
// touch errno.
error(QString("%1: Error reading input file: %2")
.arg(filename()).arg(strerror(errno)));
return false;
}
if (! filename().toUpper().endsWith(".LZMA")) {
// When using LZMA_CONCATENATED, we need to tell
// liblzma when it has got all the input.
if (feof(file))
action = LZMA_FINISH;
}
}
ret = lzma_code(strm, action);
// Write and check write error before checking decoder error.
// This way as much data as possible gets written to output
// even if decoder detected an error.
if (strm->avail_out == 0 || ret != LZMA_OK) {
const size_t write_size = BUFSIZ - strm->avail_out;
if (fwrite(out_buf, 1, write_size, out_file)
!= write_size) {
// Wouldn't be a surprise if writing to stderr
// would fail too but at least try to show an
// error message.
error(QString("Cannot write to standard output: %1").arg(strerror(errno)));
return false;
}
strm->next_out = out_buf;
strm->avail_out = BUFSIZ;
}
if (ret != LZMA_OK) {
if (ret == LZMA_STREAM_END) {
if (filename().toUpper().endsWith("LZMA")) {
// Check that there's no trailing garbage.
if (strm->avail_in != 0
|| fread(in_buf, 1, 1, file)
!= 0
|| !feof(file))
ret = LZMA_DATA_ERROR;
else {
return true;
}
} else {
return true;
}
}
QString msg;
switch (ret) {
case LZMA_MEM_ERROR:
msg = strerror(ENOMEM);
break;
case LZMA_MEMLIMIT_ERROR:
msg = "Memory usage limit reached";
break;
case LZMA_FORMAT_ERROR:
msg = "File format not recognized";
break;
case LZMA_OPTIONS_ERROR:
// FIXME: Better message?
msg = "Unsupported compression options";
break;
case LZMA_DATA_ERROR:
msg = "File is corrupt";
break;
case LZMA_BUF_ERROR:
msg = "Unexpected end of input";
break;
default:
msg = "Internal program error (bug)";
break;
}
error(QString("%1: %2").arg(filename()).arg(msg));
return false;
}
}
}
bool overwriteCheck(QString& filename)
{
while (QFile::exists(filename))
{
Kerfuffle::OverwriteQuery query(filename);
query.setMultiMode(false); // for single file mode
userQuery(&query);
query.waitForResponse();
if (query.responseCancelled() || query.responseSkip())
{
return false;
}
else if (query.responseOverwrite())
{
break;
}
else if (query.responseRename())
{
filename = query.newFilename();
}
}
return true;
}
bool copyFiles( const QList<QVariant> & files, const QString & destinationDirectory, ExtractionOptions options )
{
kDebug( 1601 ) ;
Q_UNUSED(files);
Q_UNUSED(options);
QString outputFilename = destinationDirectory;
if (!destinationDirectory.endsWith('/'))
outputFilename += '/';
outputFilename += uncompressedFilename();
if (!overwriteCheck(outputFilename))
return true; // just return as success
FILE *in;
FILE *out;
in = fopen(QFile::encodeName(filename()).data(), "rb");
if (in == NULL) {
return false;
}
out = fopen(QFile::encodeName(outputFilename).data(), "wb");
if (out == NULL) {
return false;
}
lzma_stream strm = LZMA_STREAM_INIT;
bool ret = lzma_uncompress(&strm, in, out);
fclose(in);
fclose(out);
return ret;
}
};
#include "lzmaplugin.moc"
KERFUFFLE_PLUGIN_FACTORY( LibLZMAInterface )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../..
${CMAKE_CURRENT_BINARY_DIR}/../..
)
set(kerfuffle_singlefile_SRCS singlefileplugin.cpp)
#
# GZip files
#
macro_optional_find_package(ZLIB)
macro_log_feature(ZLIB_FOUND "zlib" "zlib is used for the .gz format" "http://www.zlib.net" FALSE "" "Required for the .gz format support in Ark")
if (ZLIB_FOUND)
set(kerfuffle_libgz_SRCS gzplugin.cpp ${kerfuffle_singlefile_SRCS})
kde4_add_plugin(kerfuffle_libgz ${kerfuffle_libgz_SRCS})
target_link_libraries(kerfuffle_libgz ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} kerfuffle )
install(TARGETS kerfuffle_libgz DESTINATION ${PLUGIN_INSTALL_DIR} )
install( FILES kerfuffle_libgz.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
endif (ZLIB_FOUND)
#
# Bzip2 files
#
macro_optional_find_package(BZip2)
macro_log_feature(BZIP2_FOUND "bzip2" "bzip2 is used for the .bz2 format" "http://www.bzip2.org" FALSE "" "Required for the .bz2 format support in Ark")
if (BZIP2_FOUND)
set(kerfuffle_libbz2_SRCS bz2plugin.cpp ${kerfuffle_singlefile_SRCS})
kde4_add_plugin(kerfuffle_libbz2 ${kerfuffle_libbz2_SRCS})
target_link_libraries(kerfuffle_libbz2 ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} kerfuffle )
install(TARGETS kerfuffle_libbz2 DESTINATION ${PLUGIN_INSTALL_DIR} )
install( FILES kerfuffle_libbz2.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
endif (BZIP2_FOUND)
#
# LZMA files
#
macro_optional_find_package(LibLZMA)
macro_log_feature(LIBLZMA_FOUND "LibLZMA" "Liblzma is used for the .xz and .lzma formats" "http://tukaani.org/xz/" FALSE "" "Required for the .xz and .lzma format support in Ark")
if (LIBLZMA_FOUND)
set(kerfuffle_libxz_SRCS xzplugin.cpp ${kerfuffle_singlefile_SRCS})
kde4_add_plugin(kerfuffle_libxz ${kerfuffle_libxz_SRCS})
target_link_libraries(kerfuffle_libxz ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} kerfuffle )
install(TARGETS kerfuffle_libxz DESTINATION ${PLUGIN_INSTALL_DIR} )
install( FILES kerfuffle_libxz.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
endif (LIBLZMA_FOUND)
/*
* Copyright (c) 2009 Raphael Kubo da Costa <kubito@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bz2plugin.h"
#include "kerfuffle/archivefactory.h"
#include <QString>
LibBzip2Interface::LibBzip2Interface( const QString & filename, QObject *parent )
: LibSingleFileInterface( filename, parent )
{
m_mimeType = "application/x-bzip";
m_possibleExtensions.append(".bz2");
}
LibBzip2Interface::~LibBzip2Interface()
{
}
KERFUFFLE_PLUGIN_FACTORY( LibBzip2Interface )
#include "bz2plugin.moc"
/*
* Copyright (c) 2009 Raphael Kubo da Costa <kubito@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BZ2PLUGIN_H
#define BZ2PLUGIN_H
#include "singlefileplugin.h"
class LibBzip2Interface : public LibSingleFileInterface
{
Q_OBJECT
public:
LibBzip2Interface( const QString & filename, QObject *parent );
virtual ~LibBzip2Interface();
};
#endif // BZ2PLUGIN_H
/*
* Copyright (c) 2009 Raphael Kubo da Costa <kubito@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gzplugin.h"
#include "kerfuffle/archivefactory.h"
#include <QString>
LibGzipInterface::LibGzipInterface( const QString & filename, QObject *parent )
: LibSingleFileInterface( filename, parent )
{
m_mimeType = "application/x-gzip";
m_possibleExtensions.append(".gz");
}
LibGzipInterface::~LibGzipInterface()
{
}
KERFUFFLE_PLUGIN_FACTORY( LibGzipInterface )
#include "gzplugin.moc"
/*
* Copyright (c) 2009 Raphael Kubo da Costa <kubito@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GZPLUGIN_H
#define GZPLUGIN_H
#include "singlefileplugin.h"
class LibGzipInterface : public LibSingleFileInterface
{
Q_OBJECT
public:
LibGzipInterface( const QString & filename, QObject *parent );
virtual ~LibGzipInterface();
};
#endif // GZPLUGIN_H
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=Kerfuffle/Plugin
X-KDE-Library=kerfuffle_libbz2
X-KDE-PluginInfo-Author=Raphael Kubo da Costa
X-KDE-PluginInfo-Email=kubito@gmail.com
X-KDE-PluginInfo-Name=kerfuffle_libbz2
X-KDE-PluginInfo-Version=0.0.1
X-KDE-PluginInfo-Website=http://www.kde.org
X-KDE-PluginInfo-License=BSD