summaryrefslogtreecommitdiffstats
path: root/ark/tar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ark/tar.cpp')
-rw-r--r--ark/tar.cpp774
1 files changed, 774 insertions, 0 deletions
diff --git a/ark/tar.cpp b/ark/tar.cpp
new file mode 100644
index 0000000..5f104ef
--- /dev/null
+++ b/ark/tar.cpp
@@ -0,0 +1,774 @@
+/*
+
+ ark -- archiver for the KDE project
+
+ Copyright (C)
+
+ 1997-1999: Rob Palmbos palm9744@kettering.edu
+ 1999: Francois-Xavier Duranceau duranceau@kde.org
+ 1999-2000: Corel Corporation (author: Emily Ezust, emilye@corel.com)
+ 2001: Corel Corporation (author: Michael Jarrett, michaelj@corel.com)
+ 2001: Roberto Selbach Teixeira <maragato@conectiva.com>
+ 2003: Georg Robbers <Georg.Robbers@urz.uni-hd.de>
+ 2006: Henrique Pinto <henrique.pinto@kdemail.net>
+
+ 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.
+
+*/
+
+// Note: When maintaining tar files with ark, the user should be
+// aware that these options have been improved (IMHO). When you append a file
+// to a tarchive, tar does not check if the file exists already, and just
+// tacks the new one on the end. ark deletes the old one.
+// When you update a file that exists in a tarchive, it does check if
+// it exists, but once again, it creates a duplicate at the end (only if
+// the file is newer though). ark deletes the old one in this case as well.
+//
+// Basically, tar files are great for creating and extracting, but
+// not especially for maintaining. The original purpose of a tar was of
+// course, for tape backups, so this is not so surprising! -Emily
+//
+
+// C includes
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// Qt includes
+#include <qdir.h>
+#include <qregexp.h>
+#include <qeventloop.h>
+
+// KDE includes
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klargefile.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+#include <kmimetype.h>
+#include <kstandarddirs.h>
+#include <ktempdir.h>
+#include <kprocess.h>
+#include <ktar.h>
+
+// ark includes
+#include "arkwidget.h"
+#include "settings.h"
+#include "tar.h"
+#include "filelistview.h"
+#include "tarlistingthread.h"
+
+TarArch::TarArch( ArkWidget *_gui,
+ const QString & _filename, const QString & _openAsMimeType)
+ : Arch( _gui, _filename), m_tmpDir( 0 ), createTmpInProgress(false),
+ updateInProgress(false), deleteInProgress(false), fd(0),
+ m_pTmpProc( 0 ), m_pTmpProc2( 0 ), failed( false ),
+ m_dotslash( false ), m_listingThread( 0 )
+{
+ m_filesToAdd = m_filesToRemove = QStringList();
+ m_archiver_program = m_unarchiver_program = ArkSettings::tarExe();
+ verifyCompressUtilityIsAvailable( m_archiver_program );
+ verifyUncompressUtilityIsAvailable( m_unarchiver_program );
+
+ m_fileMimeType = _openAsMimeType;
+ if ( m_fileMimeType.isNull() )
+ m_fileMimeType = KMimeType::findByPath( _filename )->name();
+
+ kdDebug(1601) << "TarArch::TarArch: mimetype is " << m_fileMimeType << endl;
+
+ if ( m_fileMimeType == "application/x-tbz2" )
+ {
+ // ark treats .tar.bz2 as x-tbz, instead of duplicating the mimetype
+ // let's just alias it to the one we already handle.
+ m_fileMimeType = "application/x-tbz";
+ }
+
+ if ( m_fileMimeType == "application/x-tar" )
+ {
+ compressed = false;
+ }
+ else
+ {
+ compressed = true;
+ m_tmpDir = new KTempDir( _gui->tmpDir()
+ + QString::fromLatin1( "temp_tar" ) );
+ m_tmpDir->setAutoDelete( true );
+ m_tmpDir->qDir()->cd( m_tmpDir->name() );
+ // build the temp file name
+ KTempFile *pTempFile = new KTempFile( m_tmpDir->name(),
+ QString::fromLatin1(".tar") );
+
+ tmpfile = pTempFile->name();
+ delete pTempFile;
+
+ kdDebug(1601) << "Tmpfile will be " << tmpfile << "\n" << endl;
+ }
+}
+
+TarArch::~TarArch()
+{
+ delete m_tmpDir;
+ m_tmpDir = 0;
+
+ if ( m_listingThread && m_listingThread->finished() != true )
+ {
+ m_listingThread->wait();
+ delete m_listingThread;
+ m_listingThread = 0;
+ }
+}
+
+int TarArch::getEditFlag()
+{
+ return Arch::Extract;
+}
+
+void TarArch::updateArch()
+{
+ if (compressed)
+ {
+ updateInProgress = true;
+ int f_desc = KDE_open(QFile::encodeName(m_filename), O_CREAT | O_TRUNC | O_WRONLY, 0666);
+ if (f_desc != -1)
+ fd = fdopen( f_desc, "w" );
+ else
+ fd = NULL;
+
+ KProcess *kp = m_currentProcess = new KProcess;
+ kp->clearArguments();
+ KProcess::Communication flag = KProcess::AllOutput;
+ if ( getCompressor() == "lzop" )
+ {
+ kp->setUsePty( KProcess::Stdin, false );
+ flag = KProcess::Stdout;
+ }
+ if ( !getCompressor().isNull() )
+ *kp << getCompressor() << "-c" << tmpfile;
+ else
+ *kp << "cat" << tmpfile;
+
+
+ connect(kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(updateProgress( KProcess *, char *, int )));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ (Arch *)this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+
+ connect(kp, SIGNAL(processExited(KProcess *)),
+ this, SLOT(updateFinished(KProcess *)) );
+
+ if ( !fd || kp->start(KProcess::NotifyOnExit, flag) == false)
+ {
+ KMessageBox::error(0, i18n("Trouble writing to the archive..."));
+ emit updateDone();
+ }
+ }
+}
+
+void TarArch::updateProgress( KProcess * _proc, char *_buffer, int _bufflen )
+{
+ // we're trying to capture the output of a command like this
+ // gzip -c myarch.tar
+ // and feed the output to the archive
+ int size;
+ size = fwrite(_buffer, 1, _bufflen, fd);
+ if (size != _bufflen)
+ {
+ _proc->kill();
+ KMessageBox::error(0, i18n("Trouble writing to the archive..."));
+ kdWarning( 1601 ) << "trouble updating tar archive" << endl;
+ //kdFatal( 1601 ) << "trouble updating tar archive" << endl;
+ }
+}
+
+
+
+QString TarArch::getCompressor()
+{
+ if ( m_fileMimeType == "application/x-tarz" )
+ return QString( "compress" );
+
+ if ( m_fileMimeType == "application/x-tgz" )
+ return QString( "gzip" );
+
+ if ( m_fileMimeType == "application/x-tbz" )
+ return QString( "bzip2" );
+
+ if( m_fileMimeType == "application/x-tzo" )
+ return QString( "lzop" );
+
+ return QString::null;
+}
+
+
+QString TarArch::getUnCompressor()
+{
+ if ( m_fileMimeType == "application/x-tarz" )
+ return QString( "uncompress" );
+
+ if ( m_fileMimeType == "application/x-tgz" )
+ return QString( "gunzip" );
+
+ if ( m_fileMimeType == "application/x-tbz" )
+ return QString( "bunzip2" );
+
+ if( m_fileMimeType == "application/x-tzo" )
+ return QString( "lzop" );
+
+ return QString::null;
+}
+
+void
+TarArch::open()
+{
+ if ( compressed )
+ QFile::remove(tmpfile); // just to make sure
+ setHeaders();
+
+ clearShellOutput();
+
+ // might as well plunk the output of tar -tvf in the shell output window...
+ //
+ // Now it's essential - used later to decide whether pathnames in the
+ // tar archive are plain or start with "./"
+ KProcess *kp = m_currentProcess = new KProcess;
+
+ *kp << m_archiver_program;
+
+ if ( compressed )
+ {
+ *kp << "--use-compress-program=" + getUnCompressor();
+ }
+
+ *kp << "-tvf" << m_filename;
+
+ m_buffer = "";
+ m_header_removed = false;
+ m_finished = false;
+
+ connect(kp, SIGNAL(processExited(KProcess *)),
+ this, SLOT(slotListingDone(KProcess *)));
+ connect(kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput( KProcess *, char *, int )));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+
+ if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
+ {
+ KMessageBox::error( 0, i18n("Could not start a subprocess.") );
+ }
+
+ // We list afterwards because we want the signals at the end
+ // This unconfuses Extract Here somewhat
+
+ if ( m_fileMimeType == "application/x-tgz"
+ || m_fileMimeType == "application/x-tbz" || !compressed )
+ {
+ openFirstCreateTempDone();
+ }
+ else
+ {
+ connect( this, SIGNAL( createTempDone() ), this, SLOT( openFirstCreateTempDone() ) );
+ createTmp();
+ }
+}
+
+void TarArch::openFirstCreateTempDone()
+{
+ if ( compressed && ( m_fileMimeType != "application/x-tgz" )
+ && ( m_fileMimeType != "application/x-tbz" ) )
+ {
+ disconnect( this, SIGNAL( createTempDone() ), this, SLOT( openFirstCreateTempDone() ) );
+ }
+
+ Q_ASSERT( !m_listingThread );
+ m_listingThread = new TarListingThread( this, m_filename );
+ m_listingThread->start();
+}
+
+void TarArch::slotListingDone(KProcess *_kp)
+{
+ const QString list = getLastShellOutput();
+ FileListView *flv = m_gui->fileList();
+ if (flv!=NULL && flv->totalFiles()>0)
+ {
+ const QString firstfile = ((FileLVI *) flv->firstChild())->fileName();
+ if (list.find(QRegExp(QString("\\s\\./%1[/\\n]").arg(firstfile)))>=0)
+ {
+ m_dotslash = true;
+ kdDebug(1601) << k_funcinfo << "archive has dot-slash" << endl;
+ }
+ else
+ {
+ if (list.find(QRegExp(QString("\\s%1[/\\n]").arg(firstfile)))>=0)
+ {
+ // archive doesn't have dot-slash
+ m_dotslash = false;
+ }
+ else
+ {
+ kdDebug(1601) << k_funcinfo << "cannot match '" << firstfile << "' in listing!" << endl;
+ }
+ }
+ }
+
+ delete _kp;
+ _kp = m_currentProcess = NULL;
+}
+
+void TarArch::create()
+{
+ emit sigCreate(this, true, m_filename,
+ Arch::Extract | Arch::Delete | Arch::Add
+ | Arch::View);
+}
+
+void TarArch::setHeaders()
+{
+ ColumnList list;
+
+ list.append(FILENAME_COLUMN);
+ list.append(PERMISSION_COLUMN);
+ list.append(OWNER_COLUMN);
+ list.append(GROUP_COLUMN);
+ list.append(SIZE_COLUMN);
+ list.append(TIMESTAMP_COLUMN);
+ list.append(LINK_COLUMN);
+
+ emit headers( list );
+}
+
+void TarArch::createTmp()
+{
+ if ( compressed )
+ {
+ if ( !QFile::exists(tmpfile) )
+ {
+ QString strUncompressor = getUnCompressor();
+ // at least lzop doesn't want to pipe zerosize/nonexistent files
+ QFile originalFile( m_filename );
+ if ( strUncompressor != "gunzip" && strUncompressor !="bunzip2" &&
+ ( !originalFile.exists() || originalFile.size() == 0 ) )
+ {
+ QFile temp( tmpfile );
+ temp.open( IO_ReadWrite );
+ temp.close();
+ emit createTempDone();
+ return;
+ }
+ // the tmpfile does not yet exist, so we create it.
+ createTmpInProgress = true;
+ int f_desc = KDE_open(QFile::encodeName(tmpfile), O_CREAT | O_TRUNC | O_WRONLY, 0666);
+ if (f_desc != -1)
+ fd = fdopen( f_desc, "w" );
+ else
+ fd = NULL;
+
+ KProcess *kp = m_currentProcess = new KProcess;
+ kp->clearArguments();
+ kdDebug(1601) << "Uncompressor is " << strUncompressor << endl;
+ *kp << strUncompressor;
+ KProcess::Communication flag = KProcess::AllOutput;
+ if (strUncompressor == "lzop")
+ {
+ // setting up a pty for lzop, since it doesn't like stdin to
+ // be /dev/null ( "no filename allowed when reading from stdin" )
+ // - but it used to work without this ? ( Feb 13, 2003 )
+ kp->setUsePty( KProcess::Stdin, false );
+ flag = KProcess::Stdout;
+ *kp << "-d";
+ }
+ *kp << "-c" << m_filename;
+
+ connect(kp, SIGNAL(processExited(KProcess *)),
+ this, SLOT(createTmpFinished(KProcess *)));
+ connect(kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(createTmpProgress( KProcess *, char *, int )));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+ if (kp->start(KProcess::NotifyOnExit, flag ) == false)
+ {
+ KMessageBox::error(0, i18n("Unable to fork a decompressor"));
+ emit sigOpen( this, false, QString::null, 0 );
+ }
+ }
+ else
+ {
+ emit createTempDone();
+ kdDebug(1601) << "Temp tar already there..." << endl;
+ }
+ }
+ else
+ {
+ emit createTempDone();
+ }
+}
+
+void TarArch::createTmpProgress( KProcess * _proc, char *_buffer, int _bufflen )
+{
+ // we're trying to capture the output of a command like this
+ // gunzip -c myarch.tar.gz
+ // and put the output into tmpfile.
+
+ int size;
+ size = fwrite(_buffer, 1, _bufflen, fd);
+ if (size != _bufflen)
+ {
+ _proc->kill();
+ KMessageBox::error(0, i18n("Trouble writing to the tempfile..."));
+ //kdFatal( 1601 ) << "Trouble writing to archive(createTmpProgress)" << endl;
+ kdWarning( 1601 ) << "Trouble writing to archive(createTmpProgress)" << endl;
+ //exit(99);
+ }
+}
+
+void TarArch::deleteOldFiles(const QStringList &urls, bool bAddOnlyNew)
+ // because tar is broken. Used when appending: see addFile.
+{
+ QStringList list;
+ QString str;
+
+ QStringList::ConstIterator iter;
+ for (iter = urls.begin(); iter != urls.end(); ++iter )
+ {
+ KURL url( *iter );
+ // find the file entry in the archive listing
+ const FileLVI * lv = m_gui->fileList()->item( url.fileName() );
+ if ( !lv ) // it isn't in there, so skip it.
+ continue;
+
+ if (bAddOnlyNew)
+ {
+ // compare timestamps. If the file to be added is newer, delete the
+ // old. Otherwise we aren't adding it anyway, so we can go on to the next
+ // file with a "continue".
+
+ QFileInfo fileInfo( url.path() );
+ QDateTime addFileMTime = fileInfo.lastModified();
+ QDateTime oldFileMTime = lv->timeStamp();
+
+ kdDebug(1601) << "Old file: " << oldFileMTime.date().year() << '-' <<
+ oldFileMTime.date().month() << '-' << oldFileMTime.date().day() <<
+ ' ' << oldFileMTime.time().hour() << ':' <<
+ oldFileMTime.time().minute() << ':' << oldFileMTime.time().second() <<
+ endl;
+ kdDebug(1601) << "New file: " << addFileMTime.date().year() << '-' <<
+ addFileMTime.date().month() << '-' << addFileMTime.date().day() <<
+ ' ' << addFileMTime.time().hour() << ':' <<
+ addFileMTime.time().minute() << ':' << addFileMTime.time().second() <<
+ endl;
+
+ if (oldFileMTime >= addFileMTime)
+ {
+ kdDebug(1601) << "Old time is newer or same" << endl;
+ continue; // don't add this file to the list to be deleted.
+ }
+ }
+ list.append(str);
+
+ kdDebug(1601) << "To delete: " << str << endl;
+ }
+ if(!list.isEmpty())
+ remove(&list);
+ else
+ emit removeDone();
+}
+
+
+void TarArch::addFile( const QStringList& urls )
+{
+ m_filesToAdd = urls;
+ // tar is broken. If you add a file that's already there, it gives you
+ // two entries for that name, whether you --append or --update. If you
+ // extract by name, it will give you
+ // the first one. If you extract all, the second one will overwrite the
+ // first. So we'll first delete all the old files matching the names of
+ // those in urls.
+ m_bNotifyWhenDeleteFails = false;
+ connect( this, SIGNAL( removeDone() ), this, SLOT( deleteOldFilesDone() ) );
+ deleteOldFiles(urls, ArkSettings::replaceOnlyWithNewer());
+}
+
+void TarArch::deleteOldFilesDone()
+{
+ disconnect( this, SIGNAL( removeDone() ), this, SLOT( deleteOldFilesDone() ) );
+ m_bNotifyWhenDeleteFails = true;
+
+ connect( this, SIGNAL( createTempDone() ), this, SLOT( addFileCreateTempDone() ) );
+ createTmp();
+}
+
+void TarArch::addFileCreateTempDone()
+{
+ disconnect( this, SIGNAL( createTempDone() ), this, SLOT( addFileCreateTempDone() ) );
+ QStringList * urls = &m_filesToAdd;
+
+ KProcess *kp = m_currentProcess = new KProcess;
+ *kp << m_archiver_program;
+
+ if( ArkSettings::replaceOnlyWithNewer())
+ *kp << "uvf";
+ else
+ *kp << "rvf";
+
+ if (compressed)
+ *kp << tmpfile;
+ else
+ *kp << m_filename;
+
+ QStringList::ConstIterator iter;
+ KURL url( urls->first() );
+ QDir::setCurrent( url.directory() );
+ for (iter = urls->begin(); iter != urls->end(); ++iter )
+ {
+ KURL fileURL( *iter );
+ *kp << fileURL.fileName();
+ }
+
+ // debugging info
+ QValueList<QCString> list = kp->args();
+ QValueList<QCString>::Iterator strTemp;
+ for ( strTemp=list.begin(); strTemp != list.end(); ++strTemp )
+ {
+ kdDebug(1601) << *strTemp << " " << endl;
+ }
+
+ connect( kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+
+ connect( kp, SIGNAL(processExited(KProcess*)), this,
+ SLOT(slotAddFinished(KProcess*)));
+
+ if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
+ {
+ KMessageBox::error( 0, i18n("Could not start a subprocess.") );
+ emit sigAdd(false);
+ }
+}
+
+void TarArch::slotAddFinished(KProcess *_kp)
+{
+ disconnect( _kp, SIGNAL(processExited(KProcess*)), this,
+ SLOT(slotAddFinished(KProcess*)));
+ m_pTmpProc = _kp;
+ m_filesToAdd = QStringList();
+ if ( compressed )
+ {
+ connect( this, SIGNAL( updateDone() ), this, SLOT( addFinishedUpdateDone() ) );
+ updateArch();
+ }
+ else
+ addFinishedUpdateDone();
+}
+
+void TarArch::addFinishedUpdateDone()
+{
+ if ( compressed )
+ disconnect( this, SIGNAL( updateDone() ), this, SLOT( addFinishedUpdateDone() ) );
+ Arch::slotAddExited( m_pTmpProc ); // this will delete _kp
+ m_pTmpProc = NULL;
+}
+
+void TarArch::unarchFileInternal()
+{
+ QString dest;
+
+ if (m_destDir.isEmpty() || m_destDir.isNull())
+ {
+ kdError(1601) << "There was no extract directory given." << endl;
+ return;
+ }
+ else dest = m_destDir;
+
+ QString tmp;
+
+ KProcess *kp = m_currentProcess = new KProcess;
+ kp->clearArguments();
+
+ *kp << m_archiver_program;
+ if (compressed)
+ *kp << "--use-compress-program="+getUnCompressor();
+
+ QString options = "-x";
+ if (!ArkSettings::extractOverwrite())
+ options += "k";
+ if (ArkSettings::preservePerms())
+ options += "p";
+ options += "f";
+
+ kdDebug(1601) << "Options were: " << options << endl;
+ *kp << options << m_filename << "-C" << dest;
+
+ // if the list is empty, no filenames go on the command line,
+ // and we then extract everything in the archive.
+ if (m_fileList)
+ {
+ for ( QStringList::Iterator it = m_fileList->begin();
+ it != m_fileList->end(); ++it )
+ {
+ *kp << QString(m_dotslash ? "./" : "")+(*it);
+ }
+ }
+
+ connect( kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+
+ connect( kp, SIGNAL(processExited(KProcess*)), this,
+ SLOT(slotExtractExited(KProcess*)));
+
+ if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
+ {
+ KMessageBox::error( 0, i18n("Could not start a subprocess.") );
+ emit sigExtract(false);
+ }
+
+}
+
+void TarArch::remove(QStringList *list)
+{
+ deleteInProgress = true;
+ m_filesToRemove = *list;
+ connect( this, SIGNAL( createTempDone() ), this, SLOT( removeCreateTempDone() ) );
+ createTmp();
+}
+
+void TarArch::removeCreateTempDone()
+{
+ disconnect( this, SIGNAL( createTempDone() ), this, SLOT( removeCreateTempDone() ) );
+
+ QString name, tmp;
+ KProcess *kp = m_currentProcess = new KProcess;
+ kp->clearArguments();
+ *kp << m_archiver_program << "--delete" << "-f" ;
+ if (compressed)
+ *kp << tmpfile;
+ else
+ *kp << m_filename;
+
+ QStringList::Iterator it = m_filesToRemove.begin();
+ for ( ; it != m_filesToRemove.end(); ++it )
+ {
+ *kp << QString(m_dotslash ? "./" : "")+(*it);
+ }
+ m_filesToRemove = QStringList();
+
+ connect( kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+ connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
+
+ connect( kp, SIGNAL(processExited(KProcess*)), this,
+ SLOT(slotDeleteExited(KProcess*)));
+
+ if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
+ {
+ KMessageBox::error( 0, i18n("Could not start a subprocess.") );
+ emit sigDelete(false);
+ }
+}
+
+void TarArch::slotDeleteExited(KProcess *_kp)
+{
+ m_pTmpProc2 = _kp;
+ if ( compressed )
+ {
+ connect( this, SIGNAL( updateDone() ), this, SLOT( removeUpdateDone() ) );
+ updateArch();
+ }
+ else
+ removeUpdateDone();
+}
+
+void TarArch::removeUpdateDone()
+{
+ if ( compressed )
+ disconnect( this, SIGNAL( updateDone() ), this, SLOT( removeUpdateDone() ) );
+
+ deleteInProgress = false;
+ emit removeDone();
+ Arch::slotDeleteExited( m_pTmpProc2 );
+ m_pTmpProc = NULL;
+}
+
+void TarArch::addDir(const QString & _dirName)
+{
+ QStringList list;
+ list.append(_dirName);
+ addFile(list);
+}
+
+void TarArch::openFinished( KProcess * )
+{
+ // do nothing
+ // turn off busy light (when someone makes one)
+ kdDebug(1601) << "Open finshed" << endl;
+}
+
+void TarArch::createTmpFinished( KProcess *_kp )
+{
+ createTmpInProgress = false;
+ fclose(fd);
+ delete _kp;
+ _kp = m_currentProcess = NULL;
+
+ emit createTempDone();
+}
+
+void TarArch::updateFinished( KProcess *_kp )
+{
+ fclose(fd);
+ updateInProgress = false;
+ delete _kp;
+ _kp = m_currentProcess = NULL;
+
+ emit updateDone();
+}
+
+void TarArch::customEvent( QCustomEvent *ev )
+{
+ if ( ev->type() == 65442 )
+ {
+ ListingEvent *event = static_cast<ListingEvent*>( ev );
+ switch ( event->status() )
+ {
+ case ListingEvent::Normal:
+ m_gui->fileList()->addItem( event->columns() );
+ break;
+
+ case ListingEvent::Error:
+ m_listingThread->wait();
+ delete m_listingThread;
+ m_listingThread = 0;
+ emit sigOpen( this, false, QString::null, 0 );
+ break;
+
+ case ListingEvent::ListingFinished:
+ m_listingThread->wait();
+ delete m_listingThread;
+ m_listingThread = 0;
+ emit sigOpen( this, true, m_filename,
+ Arch::Extract | Arch::Delete | Arch::Add | Arch::View );
+ }
+ }
+}
+
+#include "tar.moc"
+// kate: space-indent on;