Hi,
The following patch adds libarchive support in place of zlib/libtar as a
compile time option. I started looking into this when I realized out
that libtar is not included with openSUSE. It appears that libtar is not
really maintained anymore, or the at least the future seems to be
questionable. Libarchive is actively maintained, and a bit more
powerful.
Libarchive has compression handling integrated, so no need for zlib and
unzipping before untaring. Also libarchive supports other archive
formats. I have tested drumkits created as gzipped-tar bzip2-tar
and .zip files.
Libarchive seems to be standard with popular linux distros. Not sure how
available it is on OS X or Windows. I created it as a compile time
option in case someone needs libtar. And the libtar implementation works
just fine.
Setting libarchive=1 on the scons command line will use libarchive
instead of libtar. Default is libtar. I didn't enable this with
"configure/make". You need to use scons for this option (unless someone
wants to setup the configure script).
-Scott
Index: libs/hydrogen/src/sound_library.cpp
===================================================================
--- libs/hydrogen/src/sound_library.cpp (revision 233)
+++ libs/hydrogen/src/sound_library.cpp (working copy)
@@ -33,8 +33,14 @@
#include <cstdlib>
-#include <zlib.h> // used for drumkit install
-#include <libtar.h> // used for drumkit install
+#ifdef LIBARCHIVE_SUPPORT
+#include <archive.h> // used for drumkit install
+#include <archive_entry.h> // used for drumkit install
+#else //use libtar
+#include <zlib.h> // used for drumkit install
+#include <libtar.h> // used for drumkit install
+#endif
+
#include <fcntl.h>
#include <errno.h>
@@ -127,49 +133,95 @@
}
}
-
-
+#ifdef LIBARCHIVE_SUPPORT
void Drumkit::install( const QString& filename )
{
_INFOLOG( "[Drumkit::install] drumkit = " + filename );
QString dataDir = Preferences::getInstance()->getDataDirectory();
- // GUNZIP !!!
- QString gunzippedName = filename.left( filename.indexOf( "." ) );
- gunzippedName += ".tar";
- FILE *pGunzippedFile = fopen( gunzippedName.toAscii(), "wb" );
- gzFile gzipFile = gzopen( filename.toAscii(), "rb" );
- uchar buf[4096];
- while ( gzread( gzipFile, buf, 4096 ) > 0 ) {
- fwrite( buf, sizeof( uchar ), 4096, pGunzippedFile );
+ int r;
+ struct archive *drumkitFile;
+ struct archive_entry *entry;
+ char newpath[1024];
+
+ drumkitFile = archive_read_new();
+ archive_read_support_compression_all(drumkitFile);
+ archive_read_support_format_all(drumkitFile);
+ if (( r = archive_read_open_file(drumkitFile, filename.toAscii(), 10240) )) {
+ _ERRORLOG( QString( "Error: %2, Could not open drumkit: %1" )
+ .arg( archive_errno(drumkitFile))
+ .arg( archive_error_string(drumkitFile)) );
+ archive_read_close(drumkitFile);
+ archive_read_finish(drumkitFile);
+ return;
}
- gzclose( gzipFile );
- fclose( pGunzippedFile );
+ while ( (r = archive_read_next_header(drumkitFile, &entry)) != ARCHIVE_EOF) {
+ if (r != ARCHIVE_OK) {
+ _ERRORLOG( QString( "Error reading drumkit file: %1")
+ .arg(archive_error_string(drumkitFile)));
+ break;
+ }
+ // insert data directory prefix
+ QString np = dataDir + archive_entry_pathname(entry);
+ strcpy( newpath, np.toAscii() );
+ archive_entry_set_pathname(entry, newpath);
- // UNTAR !!!
- TAR *tarFile;
+ // extract tarball
+ r = archive_read_extract(drumkitFile, entry, 0);
+ if (r == ARCHIVE_WARN) {
+ _WARNINGLOG( QString( "warning while extracting %1 (%2)")
+ .arg(filename).arg(archive_error_string(drumkitFile)));
+ } else if (r != ARCHIVE_OK) {
+ _ERRORLOG( QString( "error while extracting %1 (%2)")
+ .arg(filename).arg(archive_error_string(drumkitFile)));
+ break;
+ }
+ }
+ archive_read_close(drumkitFile);
+ archive_read_finish(drumkitFile);
+}
+#else //use libtar
+void Drumkit::install( const QString& filename )
+{
+ _INFOLOG( "[Drumkit::install] drumkit = " + filename );
+ QString dataDir = Preferences::getInstance()->getDataDirectory();
- char tarfilename[1024];
- strcpy( tarfilename, gunzippedName.toAscii() );
+ // GUNZIP !!!
+ QString gunzippedName = filename.left( filename.indexOf( "." ) );
+ gunzippedName += ".tar";
+ FILE *pGunzippedFile = fopen( gunzippedName.toAscii(), "wb" );
+ gzFile gzipFile = gzopen( filename.toAscii(), "rb" );
+ uchar buf[4096];
+ while ( gzread( gzipFile, buf, 4096 ) > 0 ) {
+ fwrite( buf, sizeof( uchar ), 4096, pGunzippedFile );
+ }
+ gzclose( gzipFile );
+ fclose( pGunzippedFile );
- if ( tar_open( &tarFile, tarfilename, NULL, O_RDONLY, 0, TAR_VERBOSE | TAR_GNU ) == -1 ) {
- _ERRORLOG( QString( "[Drumkit::install] tar_open(): %1" ).arg( strerror( errno ) ) );
- }
- char destDir[1024];
- strcpy( destDir, dataDir.toAscii() );
- if ( tar_extract_all( tarFile, destDir ) != 0 ) {
- _ERRORLOG( QString( "[Drumkit::install] tar_extract_all(): %1" ).arg( strerror( errno ) ) );
- }
+ // UNTAR !!!
+ TAR *tarFile;
- if ( tar_close( tarFile ) != 0 ) {
- _ERRORLOG( QString( "[Drumkit::install] tar_close(): %1" ).arg( strerror( errno ) ) );
- }
-}
+ char tarfilename[1024];
+ strcpy( tarfilename, gunzippedName.toAscii() );
+ if ( tar_open( &tarFile, tarfilename, NULL, O_RDONLY, 0, TAR_VERBOSE | TAR_GNU ) == -1 ) {
+ _ERRORLOG( QString( "[Drumkit::install] tar_open(): %1" ).arg( strerror( errno ) ) );
+ }
+ char destDir[1024];
+ strcpy( destDir, dataDir.toAscii() );
+ if ( tar_extract_all( tarFile, destDir ) != 0 ) {
+ _ERRORLOG( QString( "[Drumkit::install] tar_extract_all(): %1" ).arg( strerror( errno ) ) );
+ }
+ if ( tar_close( tarFile ) != 0 ) {
+ _ERRORLOG( QString( "[Drumkit::install] tar_close(): %1" ).arg( strerror( errno ) ) );
+ }
+}
+#endif
+
void Drumkit::save( const QString& sName, const QString& sAuthor, const QString& sInfo, const QString& sLicense )
{
_INFOLOG( "Saving drumkit" );
Index: Sconstruct
===================================================================
--- Sconstruct (revision 233)
+++ Sconstruct (working copy)
@@ -55,6 +55,7 @@
if alsa: cppflags += " -DALSA_SUPPORT"
if jack: cppflags += " -DJACK_SUPPORT"
if lash: cppflags += " -DLASH_SUPPORT"
+ if libarchive: cppflags += " -DLIBARCHIVE_SUPPORT"
cppflags += " -DFLAC_SUPPORT"
cppflags += " -DLADSPA_SUPPORT"
@@ -160,12 +161,13 @@
env.Append( LIBS = lib_hydrogen )
env.Append( LIBS = ["sndfile"] )
- env.Append( LIBS = ["tar"] )
env.Append( LIBS = ["lrdf", "FLAC", "FLAC++"] )
if lash: env.Append( LIBS = ["lash"])
if jack: env.Append( LIBS = ["jack"])
if alsa: env.Append( LIBS = ["asound"])
+ if libarchive: env.Append( LIBS = ["archive"])
+ else: env.Append( LIBS = ["tar"])
#app = env.Program(target = 'hydrogengui', source = src, LIBS = libs )
app = env.Program(target = 'hydrogengui', source = src )
@@ -194,6 +196,7 @@
opts.Add('lash', 'Set to 1 to enable lash',0)
opts.Add('alsa', 'Set to 1 to enable alsa',1)
opts.Add('jack', 'Set to 1 to enable jack',1)
+opts.Add('libarchive', 'Set to 1 to enable libarchive instead of libtar', 0)
opts.Add('prefix','Default: /usr/local',"/usr/local")
opts.Add('destdir','Default: none',"")
@@ -203,6 +206,7 @@
lash = int(ARGUMENTS.get('lash',0))
alsa = int(ARGUMENTS.get('alsa',1))
jack = int(ARGUMENTS.get('jack',1))
+libarchive = int(ARGUMENTS.get('libarchive', 0))
install_prefix = ARGUMENTS.get('prefix',"/usr/local")
destdir = ARGUMENTS.get('destdir',"")
@@ -218,10 +222,6 @@
print 'libsndfile must be installed!'
Exit(1)
-if not conf.CheckCHeader('libtar.h'):
- print 'libtar must be installed!'
- Exit(1)
-
if not conf.CheckCHeader('lrdf.h'):
print 'lrdf must be installed!'
Exit(1)
@@ -254,10 +254,20 @@
print 'liblash must be installed!'
Exit(1)
+#libarchive: (default: disabled)
+if libarchive and not conf.CheckCHeader("archive.h"):
+ print 'libarchive must be installed!'
+ Exit(1)
+#libtar: needed if not libarchive
+elif not libarchive and not conf.CheckCHeader("zlib.h"):
+ print 'zlib devel package must be installed!'
+ Exit(1)
+elif not libarchive and not conf.CheckCHeader("libtar.h"):
+ print 'libtar must be installed!'
+ Exit(1)
-
platform = sys.platform
print ""
@@ -277,9 +287,10 @@
print "================================================================="
print "Feature Overview:\n"
-print "lash: " + printStatus( lash )
-print "alsa: " + printStatus( alsa )
-print "jack: " + printStatus( jack )
+print " lash: " + printStatus( lash )
+print " alsa: " + printStatus( alsa )
+print " jack: " + printStatus( jack )
+print "libarchive: " + printStatus( libarchive ) + (' (using libtar instead)', '')[libarchive]
print "\n================================================================="
print ""
-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Hydrogen-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel