From 8c02e414bcf9d23faf258308e3e5ad2998682581 Mon Sep 17 00:00:00 2001 From: Chris Frey Date: Thu, 23 Dec 2010 19:34:21 -0500 Subject: [PATCH] gui: ported backup GUI to use libbarrybackup --- gui/configure.ac | 21 +--- gui/po/POTFILES.in | 2 - gui/src/DeviceIface.cc | 227 +++++++------------------------------- gui/src/DeviceIface.h | 19 ++-- gui/src/Makefile.am | 7 +- gui/src/tarfile-ops-nt.cc | 112 ------------------- gui/src/tarfile.cc | 270 ---------------------------------------------- gui/src/tarfile.h | 85 --------------- 8 files changed, 50 insertions(+), 693 deletions(-) delete mode 100644 gui/src/tarfile-ops-nt.cc delete mode 100644 gui/src/tarfile.cc delete mode 100644 gui/src/tarfile.h diff --git a/gui/configure.ac b/gui/configure.ac index dfdbed50..cd131e6d 100644 --- a/gui/configure.ac +++ b/gui/configure.ac @@ -21,27 +21,8 @@ AC_PROG_LIBTOOL AC_LANG([C++]) -AC_ARG_WITH(libtar, - [ --with-libtar= root path of libtar install], - [LIBTAR_CFLAGS="-I$with_libtar/include" - LIBTAR_LIBS="-L$with_libtar/lib -ltar"], - [echo "Guessing libtar location... may not compile..."; - LIBTAR_CFLAGS="" - LIBTAR_LIBS="-ltar"]) -AC_SUBST(LIBTAR_CFLAGS) -AC_SUBST(LIBTAR_LIBS) - -AC_ARG_WITH(libz, - [ --with-zlib= root path of zlib install], - [LIBZ_CFLAGS="-I$with_libtar/include" - LIBZ_LIBS="-L$with_libtar/lib -ltar"], - [echo "Guessing zlib location... may not compile..."; - LIBZ_CFLAGS="" - LIBZ_LIBS="-lz"]) -AC_SUBST(LIBZ_CFLAGS) -AC_SUBST(LIBZ_LIBS) - PKG_CHECK_MODULES([BARRY], [libbarry-0]) +PKG_CHECK_MODULES([BARRYBACKUP], [libbarrybackup-0]) PKG_CHECK_MODULES([GTKMM], [gtkmm-2.4 libglademm-2.4 gthread-2.0]) # Carry the special tree build environment variables from parent configure, diff --git a/gui/po/POTFILES.in b/gui/po/POTFILES.in index 448e412f..23ff7721 100644 --- a/gui/po/POTFILES.in +++ b/gui/po/POTFILES.in @@ -8,8 +8,6 @@ src/barry-gui.glade src/PasswordDlg.cc src/ConfigDlg.cc -src/tarfile-ops-nt.cc -src/tarfile.cc src/main.cc src/PromptDlg.cc src/BackupWindow.cc diff --git a/gui/src/DeviceIface.cc b/gui/src/DeviceIface.cc index eed7562e..c1ea7e8c 100644 --- a/gui/src/DeviceIface.cc +++ b/gui/src/DeviceIface.cc @@ -37,8 +37,6 @@ DeviceInterface::DeviceInterface(Device *dev) , m_dbnameMutex(new Glib::Mutex) // this is just in an effort to // avoid gtkmm headers in // DeviceIface.h - , m_end_of_tar(false) - , m_tar_record_loaded(false) , m_thread_quit(false) { } @@ -64,8 +62,8 @@ void DeviceInterface::BackupThread() try { // cycle through all database names in the dbList // and store them all - Barry::ConfigFile::DBListType::const_iterator name = m_dbList.begin(); - for( ; name != m_dbList.end(); ++name ) { + Barry::ConfigFile::DBListType::const_iterator name = m_dbBackupList.begin(); + for( ; name != m_dbBackupList.end(); ++name ) { // save current db name SetThreadDBName(*name); // call the controller to do the work @@ -85,8 +83,7 @@ void DeviceInterface::BackupThread() m_last_thread_error = _("Terminated by user."); } - m_tarback->Close(); - m_tarback.reset(); + m_backup.reset(); if( error ) m_AppComm.m_error->emit(); @@ -106,18 +103,23 @@ void DeviceInterface::RestoreThread() try { // cycle until m_end_of_tar - while( !m_end_of_tar ) { + Barry::DBData meta; + while( !m_restore->EndOfFile() ) { try { - // call the controller to do the work - unsigned int dbId = m_desktop->GetDBID(m_current_dbname); - m_AppComm.m_erase_db->emit(); - m_desktop->SaveDatabase(dbId, *this); - m_AppComm.m_restored_db->emit(); + if( m_restore->GetNextMeta(meta) ) { + // save current db name + SetThreadDBName(meta.GetDBName()); + // call the controller to do the work + unsigned int dbId = m_desktop->GetDBID(meta.GetDBName()); + m_AppComm.m_erase_db->emit(); + m_desktop->SaveDatabase(dbId, *this); + m_AppComm.m_restored_db->emit(); + } } catch( Barry::Error &be ) { // save thread error m_last_thread_error = _("Error while restoring "); - m_last_thread_error += m_current_dbname + ". "; + m_last_thread_error += meta.GetDBName() + ". "; m_last_thread_error += be.what(); m_last_thread_error += _(" Will continue processing."); @@ -126,8 +128,8 @@ void DeviceInterface::RestoreThread() // skip over records from this db std::cerr << _("Error on database: ") - << m_current_dbname << std::endl; - SkipCurrentDB(); + << meta.GetDBName() << std::endl; + m_restore->SkipCurrentDB(); } } @@ -144,8 +146,7 @@ void DeviceInterface::RestoreThread() m_last_thread_error = _("Terminated by user."); } - m_tar->Close(); - m_tar.reset(); + m_restore.reset(); // signal host thread that we're done m_AppComm.m_done->emit(); @@ -185,29 +186,6 @@ std::string DeviceInterface::MakeFilename(const std::string &label) const return tarfilename.str(); } -int DeviceInterface::CountFiles(reuse::TarFile &tar, - const Barry::ConfigFile::DBListType &restoreList) const -{ - int count = 0; - std::string name, last_name; - bool good = false; - - while( tar.ReadNextFilenameOnly(name) ) { - std::string::size_type pos = name.rfind('/'); - if( pos == std::string::npos ) - continue; // bad name - std::string dbname = name.substr(0, pos); - - if( dbname != last_name ) { - last_name = dbname; - good = restoreList.IsSelected(dbname); - } - if( good ) - count++; - } - return count; -} - /// Splits a tarpath of the form "DBName/DBID" into separate string values. /// Returns true if successful, false if tarpath is a bad name. bool DeviceInterface::SplitTarPath(const std::string &tarpath, @@ -236,7 +214,6 @@ bool DeviceInterface::SplitTarPath(const std::string &tarpath, void DeviceInterface::SetThreadDBName(const std::string &dbname) { Glib::Mutex::Lock lock(*m_dbnameMutex); - m_current_dbname_not_thread_safe = dbname; m_current_dbname = dbname; } @@ -316,26 +293,14 @@ unsigned int DeviceInterface::GetRecordTotal(const Barry::ConfigFile::DBListType unsigned int DeviceInterface::GetRecordTotal(const Barry::ConfigFile::DBListType &restoreList, const std::string &filename) const { - unsigned int count = 0; - - std::auto_ptr tar; - - try { - // do a scan through the tar file - tar.reset( new reuse::TarFile(filename.c_str(), false, &reuse::gztar_ops_nonthread, true) ); - count = CountFiles(*tar, restoreList); - } - catch( reuse::TarFile::TarError &te ) { - // just throw it away - } - return count; + return Barry::Restore::GetRecordTotal(filename, restoreList, false); } /// returns name of database the thread is currently working on std::string DeviceInterface::GetThreadDBName() const { Glib::Mutex::Lock lock(*m_dbnameMutex); - return m_current_dbname_not_thread_safe; + return m_current_dbname; } bool DeviceInterface::StartBackup(AppComm comm, @@ -348,15 +313,16 @@ bool DeviceInterface::StartBackup(AppComm comm, try { std::string filename = directory + "/" + MakeFilename(backupLabel); - m_tarback.reset( new reuse::TarFile(filename.c_str(), true, &reuse::gztar_ops_nonthread, true) ); + m_backup.reset( new Barry::Backup(filename.c_str()) ); } - catch( reuse::TarFile::TarError &te ) { - return False(te.what()); + catch( Barry::BackupError &be ) { + return False(be.what()); } // setup m_AppComm = comm; - m_dbList = backupList; + m_dbBackupList = backupList; + SetThreadDBName(""); // start the thread Glib::Thread::create(sigc::mem_fun(*this, &DeviceInterface::BackupThread), false); @@ -371,25 +337,16 @@ bool DeviceInterface::StartRestore(AppComm comm, return False(_("Thread already running.")); try { - // open for the main restore - m_tar.reset( new reuse::TarFile(filename.c_str(), false, &reuse::gztar_ops_nonthread, true) ); - + m_restore.reset( new Barry::Restore(filename.c_str(), false) ); } - catch( reuse::TarFile::TarError &te ) { - return False(te.what()); + catch( Barry::BackupError &be ) { + return False(be.what()); } // setup m_AppComm = comm; - m_dbList = restoreList; - m_current_dbname_not_thread_safe = ""; - m_current_dbname = ""; - m_unique_id = 0; - m_end_of_tar = false; - m_tar_record_loaded = false; - - // get first tar record - Retrieve(); + m_restore->Add(restoreList); + SetThreadDBName(""); // start the thread Glib::Thread::create(sigc::mem_fun(*this, &DeviceInterface::RestoreThread), false); @@ -397,29 +354,13 @@ bool DeviceInterface::StartRestore(AppComm comm, } - ////////////////////////////////////////////////////////////////////////////// // Barry::Parser overrides void DeviceInterface::ParseRecord(const Barry::DBData &data, const Barry::IConverter *ic) { - m_rec_type = data.GetRecType(); - m_unique_id = data.GetUniqueId(); - std::ostringstream oss; - oss << std::hex << m_unique_id << " " << (unsigned int)m_rec_type; - m_tar_id_text = oss.str(); - if( m_tar_id_text.size() == 0 ) - throw std::runtime_error(_("No unique ID available!")); - - m_record_data.assign( - (const char*)data.GetData().GetData() + data.GetOffset(), - data.GetData().GetSize() - data.GetOffset()); - - // store in tarball - std::string tarname = m_current_dbname + "/" + m_tar_id_text; - m_tarback->AppendFile(tarname.c_str(), m_record_data); - + m_backup->ParseRecord(data, ic); m_AppComm.m_progress->emit(); // check quit flag @@ -432,85 +373,21 @@ void DeviceInterface::ParseRecord(const Barry::DBData &data, ////////////////////////////////////////////////////////////////////////////// // Barry::Builder overrides -bool DeviceInterface::Retrieve() +bool DeviceInterface::BuildRecord(Barry::DBData &data, size_t &offset, + const Barry::IConverter *ic) { - if( m_end_of_tar ) - return false; + // check quit flag + if( m_thread_quit ) { + throw Quit(); + } - // if loaded, we are likely on a database - // boundary, and the last read crossed it, so don't load again - if( m_tar_record_loaded ) + if( m_restore->BuildRecord(data, offset, ic) ) { + m_AppComm.m_progress->emit(); return true; - - // search for a valid record - for(;;) { - // load record data from tar file - std::string filename; - if( !m_tar->ReadNextFile(filename, m_record_data) ) { - // assume end of file - m_end_of_tar = true; - return false; - } - m_tar_record_loaded = true; - - // split record filename into dbname and ID - std::string dbname; - if( !SplitTarPath(filename, dbname, m_tar_id_text, m_rec_type, m_unique_id) ) { - // invalid filename, skip it - std::cerr << _("Skipping invalid tar record: ") << filename << std::endl; - continue; - } - - // are we working on the same dbname as last time? if so, go ahead! - if( m_current_dbname == dbname ) { - return true; - } - - // DIFFERENT DBNAME from here on down! - - // does the filter allow this record? if not, skip it and continue - // looking - if( !m_dbList.IsSelected(dbname) ) { - continue; - } - - // all checks pass, load the new dbname, and return false - // if we are on a dbname boundary - bool r_val = false; - if( m_current_dbname.size() == 0 ) { - // this is the first time through Retrieve, so ok - r_val = true; - } - - SetThreadDBName(dbname); - return r_val; } -} - -bool DeviceInterface::BuildRecord(Barry::DBData &data, size_t &offset, - const Barry::IConverter *ic) -{ - if( !Retrieve() ) + else { return false; - - // fill in the meta data - data.SetVersion(Barry::DBData::REC_VERSION_1); - data.SetDBName(m_current_dbname); - data.SetIds(m_rec_type, m_unique_id); - data.SetOffset(offset); - - // fill in the record data - int packet_size = offset + m_record_data.size(); - Barry::Data &block = data.UseData(); - unsigned char *buf = block.GetBuffer(packet_size); - memcpy(buf + offset, m_record_data.data(), m_record_data.size()); - offset += m_record_data.size(); - block.ReleaseBuffer(packet_size); - - // clear loaded flag, as it has now been used - m_tar_record_loaded = false; - m_AppComm.m_progress->emit(); - return true; + } } bool DeviceInterface::FetchRecord(Barry::DBData &data, @@ -520,28 +397,6 @@ bool DeviceInterface::FetchRecord(Barry::DBData &data, return BuildRecord(data, offset, ic); } -// helper function for halding restore errors -void DeviceInterface::SkipCurrentDB() throw() -{ - // skip all records until next DB - try { - while( Retrieve() ) { - std::cerr << _("Skipping: ") - << m_current_dbname << "/" - << m_tar_id_text << std::endl; - m_tar_record_loaded = false; - } - } - catch( reuse::TarFile::TarError & ) { - m_end_of_tar = true; - } - catch( ... ) { - // swallow all other exceptions - std::cerr << "EXCEPTION IN SkipCurrentDB()! " - "Please report to Barry mailing list." << std::endl; - } -} - Device::Device(const Barry::ProbeResult &result) : result(result) { diff --git a/gui/src/DeviceIface.h b/gui/src/DeviceIface.h index 4ea8cc34..ad8d984a 100644 --- a/gui/src/DeviceIface.h +++ b/gui/src/DeviceIface.h @@ -23,10 +23,10 @@ #define __BARRYBACKUP_DEVICEIFACE_H__ #include +#include #include #include #include -#include "tarfile.h" #define DI_THREAD_DONE 100 #define DI_THREAD_PROGRESS 101 @@ -102,19 +102,14 @@ private: std::string m_last_thread_error; AppComm m_AppComm; - std::auto_ptr m_tar, m_tarback; - // parser and builder data (only one side uses these at a time) - Barry::ConfigFile::DBListType m_dbList; + std::auto_ptr m_backup; + std::auto_ptr m_restore; + + // parser and builder data + Barry::ConfigFile::DBListType m_dbBackupList; mutable Glib::Mutex *m_dbnameMutex; - std::string m_current_dbname_not_thread_safe; std::string m_current_dbname; - uint8_t m_rec_type; - uint32_t m_unique_id; - std::string m_tar_id_text; - std::string m_record_data; - bool m_end_of_tar; - bool m_tar_record_loaded; // thread quit flag... not locked, only a byte volatile bool m_thread_quit; @@ -128,13 +123,11 @@ protected: // helpers std::string MakeFilename(const std::string &label = "") const; - int CountFiles(reuse::TarFile &tar, const Barry::ConfigFile::DBListType &restoreList) const; bool SplitTarPath(const std::string &tarpath, std::string &dbname, std::string &dbid_text, uint8_t &dbrectype, uint32_t &dbid) const; // Sets the name of the database the thread is currently working on void SetThreadDBName(const std::string &dbname); - bool Retrieve(); public: DeviceInterface(Device *dev = 0); diff --git a/gui/src/Makefile.am b/gui/src/Makefile.am index 8582d0ab..bac9b3c7 100644 --- a/gui/src/Makefile.am +++ b/gui/src/Makefile.am @@ -1,7 +1,7 @@ ##DEFAULT_INCLUDES = -INCLUDES = $(TREE_BUILD_CXXFLAGS) $(BARRY_CFLAGS) $(GTKMM_CFLAGS) $(LIBTAR_CFLAGS) $(LIBZ_CFLAGS) -LIBS = $(TREE_BUILD_LDFLAGS) $(BARRY_LIBS) $(GTKMM_LIBS) $(LIBTAR_LIBS) $(LIBZ_LIBS) +INCLUDES = $(TREE_BUILD_CXXFLAGS) $(BARRY_CFLAGS) $(BARRYBACKUP_CFLAGS) $(GTKMM_CFLAGS) +LIBS = $(TREE_BUILD_LDFLAGS) $(BARRY_LIBS) $(BARRYBACKUP_LIBS) $(GTKMM_LIBS) AM_CXXFLAGS = -Wall -g AM_CPPFLAGS = -DBARRYBACKUP_GLADEDIR='"$(gladedir)"' @@ -30,8 +30,6 @@ barrybackup_SOURCES = \ DeviceBus.cc \ DeviceIface.cc \ Thread.cc \ - tarfile.cc \ - tarfile-ops-nt.cc \ util.cc noinst_HEADERS= \ @@ -43,7 +41,6 @@ noinst_HEADERS= \ PasswordDlg.h \ PromptDlg.h \ Thread.h \ - tarfile.h \ util.h \ i18n.h \ gettext.h diff --git a/gui/src/tarfile-ops-nt.cc b/gui/src/tarfile-ops-nt.cc deleted file mode 100644 index 0958408b..00000000 --- a/gui/src/tarfile-ops-nt.cc +++ /dev/null @@ -1,112 +0,0 @@ -/// -/// \file tarfile-ops-nt.cc -/// Non-thread safe operation functions for a libtar-compatible -/// zlib compression interface. - -/* - Copyright (C) 2007-2010, Chris Frey - - 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 in the COPYING file at the - root directory of this project for more details. -*/ - -#include "tarfile.h" - -#include -#include -#include -#include - -#include - -#include - -namespace reuse { - -namespace gztar_nonthread { - - namespace { - // array of compressed file handles... needed for architectures - // where sizeof(int) != sizeof(gzFile) - gzFile *gzHandles = 0; - unsigned int gzArraySize = 0; - } - - int open_compressed(const char *file, int flags, mode_t mode) - { - unsigned int index = 0; - for( ; index < gzArraySize; index++ ) { - if( gzHandles[index] == 0 ) - break; - } - if( index >= gzArraySize ) { - gzFile *h = (gzFile*) realloc(gzHandles, - (gzArraySize + 100) * sizeof(gzFile)); - if( h ) { - gzHandles = h; - gzArraySize += 100; - } - else { - return -1; - } - } - - int fd = open(file, flags, mode); - if( fd == -1 ) - return -1; - - gzFile gfd = gzdopen(fd, (flags & O_WRONLY) ? "wb9" : "rb"); - if( gfd == NULL ) { - close(fd); - return -1; - } - - gzHandles[index] = gfd; - return index; - } - - int close_compressed(int fd) - { - unsigned int ufd = fd; - assert( ufd < gzArraySize ); - int ret = gzclose(gzHandles[ufd]); - gzHandles[ufd] = 0; - return ret; - } - - ssize_t read_compressed(int fd, void *buf, size_t size) - { - unsigned int ufd = fd; - assert( ufd < gzArraySize ); - return gzread(gzHandles[ufd], buf, size); - } - - ssize_t write_compressed(int fd, const void *buf, size_t size) - { - unsigned int ufd = fd; - assert( ufd < gzArraySize ); - return gzwrite(gzHandles[ufd], buf, size); - } - -} // namespace gztar_nonthread - - -tartype_t gztar_ops_nonthread = { - (openfunc_t) gztar_nonthread::open_compressed, - gztar_nonthread::close_compressed, - gztar_nonthread::read_compressed, - gztar_nonthread::write_compressed -}; - - -} // namespace reuse - diff --git a/gui/src/tarfile.cc b/gui/src/tarfile.cc deleted file mode 100644 index da0d07d8..00000000 --- a/gui/src/tarfile.cc +++ /dev/null @@ -1,270 +0,0 @@ -/// -/// \file tarfile.cc -/// API for reading and writing sequentially from compressed -/// tar files. - -/* - Copyright (C) 2007-2010, Chris Frey - - 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 in the COPYING file at the - root directory of this project for more details. -*/ - -#include "tarfile.h" - -#include -#include -#include -#include - -namespace reuse { - -TarFile::TarFile(const char *filename, - bool create, - tartype_t *compress_ops, - bool always_throw) - : m_tar(0), - m_throw(always_throw), - m_writemode(create) -{ - // figure out how to handle the file flags/modes - int flags = 0; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - - if( m_writemode ) { - flags = O_WRONLY | O_CREAT | O_EXCL; - } - else { - flags = O_RDONLY; - } - - // open... throw on error, as we are in the constructor - if( tar_open(&m_tar, const_cast(filename), - compress_ops, flags, mode, TAR_VERBOSE | TAR_GNU) == -1 ) { - throw TarError(std::string("Unable to open tar file: ") + strerror(errno)); - } -} - -TarFile::~TarFile() -{ - try { - Close(); - } catch( TarError &te ) {} -} - -bool TarFile::False(const char *msg) -{ - m_last_error = msg; - if( m_throw ) - throw TarError(msg); - else - return false; -} - -bool TarFile::False(const std::string &msg, int err) -{ - std::string str = msg; - str += ": "; - str += strerror(err); - return False(str); -} - -bool TarFile::Close() -{ - if( m_tar ) { - if( m_writemode ) { - if( tar_append_eof(m_tar) != 0 ) - return False("Unable to write eof", errno); - } - - if( tar_close(m_tar) != 0 ) { - return False("Unable to close file", errno); - } - m_tar = 0; - } - return true; -} - -/// Appends a new file to the current tarfile, using tarpath as -/// its internal filename, and data as the complete file contents. -/// Uses current date and time as file mtime. -bool TarFile::AppendFile(const char *tarpath, const std::string &data) -{ - // write standard file header - th_set_type(m_tar, REGTYPE); - th_set_mode(m_tar, 0644); - th_set_path(m_tar, const_cast(tarpath)); - th_set_user(m_tar, 0); - th_set_group(m_tar, 0); - th_set_size(m_tar, data.size()); - th_set_mtime(m_tar, time(NULL)); - if( th_write(m_tar) != 0 ) { - return False("Unable to write tar header", errno); - } - - // write the data in blocks until finished - char block[T_BLOCKSIZE]; - for( size_t pos = 0; pos < data.size(); pos += T_BLOCKSIZE ) { - memset(block, 0, T_BLOCKSIZE); - - size_t size = T_BLOCKSIZE; - if( data.size() - pos < T_BLOCKSIZE ) - size = data.size() - pos; - - memcpy(block, data.data() + pos, size); - - if( tar_block_write(m_tar, block) != T_BLOCKSIZE ) { - return False("Unable to write block", errno); - } - } - - return true; -} - -/// Reads next available file into data, filling tarpath with -/// internal filename from tarball. -bool TarFile::ReadNextFile(std::string &tarpath, std::string &data) -{ - // start fresh - tarpath.clear(); - data.clear(); - - // read next tar file header - if( th_read(m_tar) != 0 ) { - // this is not necessarily an error, as it could just - // be the end of file, so a simple false is good here, - // don't throw an exception - m_last_error = ""; - return false; - } - - // write standard file header - if( !TH_ISREG(m_tar) ) { - return False("Only regular files are supported inside a tarball."); - } - - char *pathname = th_get_pathname(m_tar); - tarpath = pathname; - // - // FIXME (leak) - someday, when all distros use a patched version of - // libtar, we may be able to avoid this memory leak, but - // th_get_pathname() does not consistently return a user-freeable - // string on all distros. - // - // See the following links for more information: - // https://bugs.launchpad.net/ubuntu/+source/libtar/+bug/41804 - // https://lists.feep.net:8080/pipermail/libtar/2006-April/000222.html - // -// free(pathname); - size_t size = th_get_size(m_tar); - - // read the data in blocks until finished - char block[T_BLOCKSIZE]; - for( size_t pos = 0; pos < size; pos += T_BLOCKSIZE ) { - memset(block, 0, T_BLOCKSIZE); - - size_t readsize = T_BLOCKSIZE; - if( size - pos < T_BLOCKSIZE ) - readsize = size - pos; - - if( tar_block_read(m_tar, block) != T_BLOCKSIZE ) { - return False("Unable to read block", errno); - } - - data.append(block, readsize); - } - - return true; -} - -/// Read next available filename, skipping the data if it is -/// a regular file -bool TarFile::ReadNextFilenameOnly(std::string &tarpath) -{ - // start fresh - tarpath.clear(); - - // read next tar file header - if( th_read(m_tar) != 0 ) { - // this is not necessarily an error, as it could just - // be the end of file, so a simple false is good here, - // don't throw an exception - m_last_error = ""; - return false; - } - - // write standard file header - if( !TH_ISREG(m_tar) ) { - return False("Only regular files are supported inside a tarball."); - } - - char *pathname = th_get_pathname(m_tar); - tarpath = pathname; - // See above FIXME (leak) comment -// free(pathname); - - if( tar_skip_regfile(m_tar) != 0 ) { - return False("Unable to skip tar file", errno); - } - - return true; -} - - -} // namespace reuse - - -#ifdef __TEST_MODE__ - -#include -#include - -using namespace std; - -int main() -{ - try { - cout << "Writing test file..." << endl; - reuse::TarFile output("tartest.tar.gz", true, true, true); - std::string data; - for( int i = 0; i < 60; i++ ) { - data.append("0123456789", 10); - } - - output.AppendFile("path1/test1.txt", data); - output.AppendFile("path2/test2.txt", data); - output.Close(); - - - cout << "Reading test file..." << endl; - reuse::TarFile input("tartest.tar.gz", false, true, true); - std::string path, incoming; - - while( input.ReadNextFile(path, incoming) ) { - cout << "Read: " << path - << " Data: " - << (( data == incoming ) ? "equal" : "different") - << endl; - } - - input.Close(); - - unlink("tartest.tar.gz"); - - } catch( reuse::TarFile::TarError &te ) { - cerr << te.what() << endl; - return 1; - } -} - -#endif - diff --git a/gui/src/tarfile.h b/gui/src/tarfile.h deleted file mode 100644 index 68c69a9a..00000000 --- a/gui/src/tarfile.h +++ /dev/null @@ -1,85 +0,0 @@ -/// -/// \file tarfile.h -/// API for reading and writing sequentially from compressed -/// tar files. - -/* - Copyright (C) 2007-2010, Chris Frey - - 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 in the COPYING file at the - root directory of this project for more details. -*/ - -#ifndef __REUSE_TARFILE_H__ -#define __REUSE_TARFILE_H__ - -#include -#include -#include - -namespace reuse { - -// -// Compression options... more op sets can be added based on -// threading needs, or threading library support. -// - -/// Compression op set for zlib, non-threadsafe. -extern tartype_t gztar_ops_nonthread; - -class TarFile -{ - TAR *m_tar; - bool m_throw; - bool m_writemode; - std::string m_last_error; - -private: - bool False(const char *msg); - bool False(const std::string &str) { return False(str.c_str()); } - bool False(const std::string &msg, int err); - -public: - class TarError : public std::runtime_error - { - public: - TarError(const std::string &msg) : std::runtime_error(msg) {} - }; - -public: - explicit TarFile(const char *filename, bool write = false, - tartype_t *compress_ops = 0, bool always_throw = false); - ~TarFile(); - - const std::string& get_last_error() const { return m_last_error; } - - bool Close(); - - /// Appends a new file to the current tarfile, using tarpath as - /// its internal filename, and data as the complete file contents. - /// Uses current date and time as file mtime. - bool AppendFile(const char *tarpath, const std::string &data); - - /// Reads next available file into data, filling tarpath with - /// internal filename from tarball. - /// Returns false on end of archive. - bool ReadNextFile(std::string &tarpath, std::string &data); - - /// Read next available filename, skipping the data if it is - /// a regular file - bool ReadNextFilenameOnly(std::string &tarpath); -}; - -} - -#endif - -- 2.11.4.GIT