Source Code (Use browser search to find items of interest.)
Class Index
ark'TarArch (./kdeutils/ark/tar.h:58)
class TarArch : public Arch
{
Q_OBJECT
public:
TarArch( ArkSettings *_settings, Viewer *_gui, const QString & _filename);
virtual ~TarArch();
virtual void open();
virtual void create();
virtual void addFile( QStringList *);
virtual void addDir(const QString &);
virtual void remove(QStringList *);
virtual void unarchFile(QStringList *, const QString & _destDir="");
virtual int getEditFlag();
QString getCompressor();
QString getUnCompressor();
public slots:
void updateProgress( KProcess *_kp, char *_buffer, int _bufflen);
void openFinished( KProcess * );
void updateFinished( KProcess * );
void createTmpFinished( KProcess * );
void createTmpProgress( KProcess *_kp, char *_buffer, int _bufflen);
void slotAddFinished(KProcess *);
void slotListingDone(KProcess *);
private: // methods
void updateArch();
void createTmp();
void setHeaders();
void processDir(const KTarDirectory *tardir, const QString & root);
private: // data
QString m_archiver_program;
// if the tar is compressed, this is the temporary uncompressed tar.
QString tmpfile;
bool compressed;
// for use with createTmp and updateArch
bool createTmpInProgress;
bool updateInProgress;
FILE *fd;
};
ark'TarArch::TarArch() (./kdeutils/ark/tar.cc:69)
TarArch::TarArch( ArkSettings *_settings, Viewer *_gui,
const QString & _filename)
: Arch(_settings, _gui, _filename), createTmpInProgress(false),
updateInProgress(false), fd(NULL)
{
kdDebug(1601) << "+TarArch::TarArch" << endl;
m_archiver_program = m_settings->getTarCommand();
_settings->readTarProperties();
if (_filename.right(4) == ".tar")
{
compressed = false;
}
else
{
compressed = true;
QString tmpdir;
tmpdir.sprintf("/tmp/ark.%d", getpid());
QString base = m_filename.right(m_filename.length()- 1 -
m_filename.findRev("/"));
base = base.left(base.findRev("."));
// build the temp file name
tmpfile.sprintf("%s/temp_tar_%s.%d", (const char *)tmpdir,
(const char *)base, getpid());
kdDebug(1601) << "Tmpfile will be " << (const char *)tmpfile.local8Bit() << "\n" << endl;
}
kdDebug(1601) << "-TarArch::TarArch" << endl;
}
ark'TarArch::~TarArch() (./kdeutils/ark/tar.cc:100)
TarArch::~TarArch()
{
unlink((const char *)tmpfile);
}
ark'TarArch::getEditFlag() (./kdeutils/ark/tar.cc:105)
int TarArch::getEditFlag()
{
return Arch::Extract;
}
ark'TarArch::updateArch() (./kdeutils/ark/tar.cc:110)
void TarArch::updateArch()
{
kdDebug(1601) << "+TarArch::updateArch" << endl;
if (compressed)
{
updateInProgress = true;
fd = fopen( m_filename.local8Bit(), "w" );
KProcess *kp = new KProcess;
kp->clearArguments();
*kp << getCompressor() << "-c" << tmpfile.local8Bit();
connect(kp, SIGNAL(receivedStdout(KProcess*, char*, int)),
this, SLOT(updateProgress( KProcess *, char *, int )));
connect( kp, SIGNAL(receivedStderr(KProcess*, char*, int)),
this, SLOT(slotReceivedOutput(KProcess*, char*, int)));
connect(kp, SIGNAL(processExited(KProcess *)),
this, SLOT(updateFinished(KProcess *)) );
if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
{
KMessageBox::error(0, i18n("Trouble writing to the archive..."));
}
}
kdDebug(1601) << "-TarArch::updateArch" << endl;
}
ark'TarArch::updateProgress() (./kdeutils/ark/tar.cc:137)
void TarArch::updateProgress( KProcess *, 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)
{
KMessageBox::error(0, i18n("Trouble writing to the archive..."));
exit(99);
}
}
ark'TarArch::getCompressor() (./kdeutils/ark/tar.cc:153)
QString TarArch::getCompressor()
{
QString extension = m_filename.right(m_filename.length() -
m_filename.findRev('.') );
kdDebug(1601) << "Extension: " << (const char *)extension << endl;
if( extension == ".tgz" || extension == ".gz" )
return QString( "gzip" );
if( extension == ".bz")
return QString( "bzip" );
if( extension == ".Z" || extension == ".taz" )
return QString( "compress" );
if( extension == ".bz2")
return QString( "bzip2" );
if( extension == ".lzo" || extension == ".tzo" )
return QString( "lzop" );
return QString::null;
}
ark'TarArch::getUnCompressor() (./kdeutils/ark/tar.cc:172)
QString TarArch::getUnCompressor()
{
QString extension = m_filename.right(m_filename.length() -
m_filename.findRev('.'));
kdDebug(1601) << "Extension: " << (const char *)extension << endl;
if( extension == ".tgz" || extension == ".gz" )
return QString( "gunzip" );
if( extension == ".bz")
return QString( "bunzip" );
if( extension == ".Z" || extension == ".taz" )
return QString( "uncompress" );
if( extension == ".bz2")
return QString( "bunzip2" );
if( extension == ".lzo" || extension == ".tzo" )
return QString( "lzop" );
return QString::null;
}
ark'TarArch::open() (./kdeutils/ark/tar.cc:190)
void TarArch::open()
{
kdDebug(1601) << "+TarArch::open" << endl;
unlink((const char *)tmpfile); // just to make sure
setHeaders();
KTarGz *tarptr;
if (!compressed ||
getUnCompressor() == QString("gunzip"))
{
tarptr = new KTarGz(m_filename);
}
else
{
createTmp();
while (compressed && createTmpInProgress)
qApp->processEvents(); // wait for temp to be created;
tarptr = new KTarGz(tmpfile);
}
if (! tarptr->open(IO_ReadOnly))
{
emit sigOpen(this, false, QString::null, 0 );
}
else
{
processDir(tarptr->directory(), "");
// because we aren't using the KProcess method, we have to emit this
// ourselves.
emit sigOpen(this, true, m_filename,
Arch::Extract | Arch::Delete | Arch::Add | Arch::View );
}
delete tarptr;
// might as well plunk the output of tar -tvf in the shell output window...
KProcess *kp = new KProcess;
*kp << m_archiver_program.local8Bit() ;
if (compressed)
*kp << "--use-compress-program="+getUnCompressor() ;
*kp << "-tvf" << m_filename.local8Bit();
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("Error in trying to list the contents of the archive."));
}
kdDebug(1601) << "-TarArch::open" << endl;
}
ark'TarArch::slotListingDone() (./kdeutils/ark/tar.cc:246)
void TarArch::slotListingDone(KProcess *_kp)
{
delete _kp;
}
ark'TarArch::processDir() (./kdeutils/ark/tar.cc:251)
void TarArch::processDir(const KTarDirectory *tardir, const QString & root)
// process a KTarDirectory. Called recursively for directories within
// directories, etc. Prepends to filename root, for relative pathnames.
{
kdDebug(1601) << "+TarArch::processDir" << endl;
QStringList list = tardir->entries();
for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
{
const KTarEntry* tarEntry = tardir->entry((*it));
if (tarEntry == NULL)
return;
QStringList col_list;
QString name;
if (root.isEmpty() || root.isNull())
name = tarEntry->name();
else
name = root + "/" + tarEntry->name();
col_list.append(QString::fromLocal8Bit(name));
QString perms = makeAccessString(tarEntry->permissions());
if (!tarEntry->isFile())
perms = "d" + perms;
else if (!tarEntry->symlink().isEmpty())
perms = "l" + perms;
else
perms = "-" + perms;
col_list.append(QString::fromLocal8Bit(perms));
QString usergroup = tarEntry->user();
usergroup += '/';
usergroup += tarEntry->group();
col_list.append(QString::fromLocal8Bit(usergroup));
QString strSize = "0";
if (tarEntry->isFile())
{
strSize.sprintf("%d", ((KTarFile *)tarEntry)->size());
}
col_list.append(QString::fromLocal8Bit(strSize));
QString timestamp = makeTimeStamp(tarEntry->datetime());
col_list.append(QString::fromLocal8Bit(timestamp));
col_list.append(QString::fromLocal8Bit(tarEntry->symlink()));
m_gui->add(&col_list); // send the entry to the GUI
// if it isn't a file, it's a directory - process it.
// remember that name is root + / + the name of the directory
if (!tarEntry->isFile())
processDir( (KTarDirectory *)tarEntry, name);
}
kdDebug(1601) << "-TarArch::processDir" << endl;
}
ark'TarArch::create() (./kdeutils/ark/tar.cc:300)
void TarArch::create()
{
kdDebug(1601) << "+TarArch::createArch" << endl;
emit sigCreate(this, true, m_filename,
Arch::Extract | Arch::Delete | Arch::Add
| Arch::View);
kdDebug(1601) << "-TarArch::createArch" << endl;
}
ark'TarArch::setHeaders() (./kdeutils/ark/tar.cc:310)
void TarArch::setHeaders()
{
kdDebug(1601) << "+TarArch::setHeaders" << endl;
QStringList list;
list.append(FILENAME_STRING);
list.append(PERMISSION_STRING);
list.append(OWNER_GROUP_STRING);
list.append(SIZE_STRING);
list.append(TIMESTAMP_STRING);
list.append(LINK_STRING);
// which columns to align right
int *alignRightCols = new int[2];
alignRightCols[0] = 1;
alignRightCols[1] = 3;
m_gui->setHeaders(&list, alignRightCols, 2);
delete [] alignRightCols;
kdDebug(1601) << "-TarArch::setHeaders" << endl;
}
ark'TarArch::createTmp() (./kdeutils/ark/tar.cc:333)
void TarArch::createTmp()
{
kdDebug(1601) << "+TarArch::createTmp" << endl;
if (compressed)
{
struct stat statbuffer;
if (stat((const char *)tmpfile, &statbuffer) == -1)
{
// the tmpfile does not yet exist, so we create it.
createTmpInProgress = true;
fd = fopen( tmpfile.local8Bit(), "w" );
KProcess *kp = new KProcess;
kp->clearArguments();
QString strUncompressor = getUnCompressor();
kdDebug(1601) << "Uncompressor is " << (const char *)strUncompressor << endl;
*kp << strUncompressor;
if (strUncompressor == "lzop")
{
*kp << "-d" ;
}
*kp << "-c" << m_filename.local8Bit();
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, KProcess::AllOutput) == false)
{
KMessageBox::error(0, i18n("I can't fork a decompressor"));
}
}
else
{
kdDebug(1601) << "Temp tar already there..." << endl;
}
}
kdDebug(1601) << "-TarArch::createTmp" << endl;
}
ark'TarArch::createTmpProgress() (./kdeutils/ark/tar.cc:376)
void TarArch::createTmpProgress( KProcess *, 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)
{
KMessageBox::error(0, i18n("Trouble writing to the tempfile..."));
exit(99);
}
}
ark'TarArch::addFile() (./kdeutils/ark/tar.cc:391)
void TarArch::addFile( QStringList* urls )
{
kdDebug(1601) << "+TarArch::addFile" << endl;
QString file, url, tmp;
createTmp();
while (compressed && createTmpInProgress)
qApp->processEvents(); // wait for temp to be created;
url = urls->first();
file = KURL(url).path(-1); // remove trailing slash
KProcess *kp = new KProcess;
kp->clearArguments();
*kp << m_archiver_program.local8Bit();
if( m_settings->getReplaceOnlyNew())
*kp << "uvf";
else
*kp << "rvf";
if (compressed)
*kp << tmpfile.local8Bit();
else
*kp << m_filename;
QString base;
if( !m_settings->getaddPath() )
{
int pos;
pos = file.findRev( '/', -1, FALSE );
base = file.left( ++pos );
kdDebug(1601) << "base is " << (const char *)base << endl;
// pos++;
tmp = file.right( file.length()-pos );
file = tmp;
chdir( base.local8Bit() );
}
QStringList::Iterator it=urls->begin();
while(1)
{
int pos;
*kp << file.local8Bit();
it++;
url = *it;
if( url.isNull() )
break;
file = KURL(url).path(-1); // remove trailing slash
pos = file.findRev( '/', -1, FALSE );
pos++;
tmp = file.right( file.length()-pos );
file = tmp;
}
// debugging info
QString strTemp;
const QStrList *ptr = kp->args();
QStrList list(*ptr); // copied because of const probs
for ( strTemp=list.first(); strTemp != 0; strTemp=list.next() )
{
kdDebug(1601) << (const char *)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*)));
kdDebug(1601) << "Busy loop... waiting for temp tar to be created" << endl;
while (compressed && createTmpInProgress)
qApp->processEvents(); // wait for temp to be created;
if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
{
KMessageBox::error( 0, i18n("Couldn't start a subprocess.") );
emit sigAdd(false);
}
#if 0
if( m_settings->getaddPath() )
file.remove( 0, 1 ); // Get rid of leading /
#endif
kdDebug(1601) << "-TarArch::addFile" << endl;
}
ark'TarArch::slotAddFinished() (./kdeutils/ark/tar.cc:481)
void TarArch::slotAddFinished(KProcess *_kp)
{
kdDebug(1601) << "+TarArch::slotAddFinished" << endl;
disconnect( _kp, SIGNAL(processExited(KProcess*)), this,
SLOT(slotAddFinished(KProcess*)));
if (compressed)
{
updateArch();
while (updateInProgress)
qApp->processEvents(); // wait for update;
}
Arch::slotAddExited(_kp); // this will delete _kp
kdDebug(1601) << "-TarArch::slotAddFinished" << endl;
}
ark'TarArch::unarchFile() (./kdeutils/ark/tar.cc:497)
void TarArch::unarchFile( QStringList * _fileList, const QString & _destDir)
{
kdDebug(1601) << "+TarArch::unarchFile" << endl;
QString dest;
if (_destDir.isEmpty() || _destDir.isNull())
dest = m_settings->getExtractDir();
else dest = _destDir;
QString tmp;
KProcess *kp = new KProcess;
kp->clearArguments();
*kp << m_archiver_program.local8Bit();
if (compressed)
*kp << "--use-compress-program="+getUnCompressor() ;
if (m_settings->getTarPreservePerms())
*kp << "-xvpf";
else
*kp << "-xvf";
*kp << m_filename.local8Bit() << "-C" << dest;
// if the list is empty, no filenames go on the command line,
// and we then extract everything in the archive.
if (_fileList)
{
for ( QStringList::Iterator it = _fileList->begin();
it != _fileList->end(); ++it )
{
*kp << (*it).latin1() ;
}
}
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("Couldn't start a subprocess.") );
emit sigExtract(false);
}
kdDebug(1601) << "+TarArch::unarchFile" << endl;
}
ark'TarArch::remove() (./kdeutils/ark/tar.cc:549)
void TarArch::remove(QStringList *list)
{
kdDebug(1601) << "+Tar::deleteFiles" << endl;
QString name, tmp;
createTmp();
while (compressed && createTmpInProgress)
qApp->processEvents(); // wait for temp to be created;
KProcess *kp = new KProcess;
kp->clearArguments();
*kp << m_archiver_program.local8Bit() << "--delete" << "-f" ;
if (compressed)
*kp << tmpfile.local8Bit();
else
*kp << m_filename.local8Bit();
for ( QStringList::Iterator it = list->begin(); it != list->end(); ++it )
{
kdDebug(1601) << (const char *)*it << endl;
*kp << *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(slotDeleteExited(KProcess*)));
if (kp->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false)
{
KMessageBox::error( 0, i18n("Couldn't start a subprocess.") );
emit sigDelete(false);
}
if (compressed)
updateArch();
kdDebug(1601) << "-Tar::deleteFiles" << endl;
}
ark'TarArch::addDir() (./kdeutils/ark/tar.cc:593)
void TarArch::addDir(const QString & _dirName)
{
QStringList list;
list.append(_dirName);
addFile(&list);
}
ark'TarArch::openFinished() (./kdeutils/ark/tar.cc:600)
void TarArch::openFinished( KProcess * )
{
// do nothing
// turn off busy light (when someone makes one)
kdDebug(1601) << "Open finshed" << endl;
}
ark'TarArch::createTmpFinished() (./kdeutils/ark/tar.cc:607)
void TarArch::createTmpFinished( KProcess *_kp )
{
kdDebug(1601) << "+TarArch::createTmpFinished" << endl;
createTmpInProgress = false;
fclose(fd);
delete _kp;
_kp = NULL;
// turn off busy light (when someone makes one)
kdDebug(1601) << "-TarArch::createTmpFinished" << endl;
}
ark'TarArch::updateFinished() (./kdeutils/ark/tar.cc:621)
void TarArch::updateFinished( KProcess *_kp )
{
kdDebug(1601) << "+TarArch::updateFinished" << endl;
fclose(fd);
updateInProgress = false;
delete _kp;
_kp = NULL;
kdDebug(1601) << "-TarArch::updateFinished" << endl;
}
////////////////////////////////////////////////////////////////////////
/////////////////// some helper functions
///////////////////////////////////////////////////////////////////////
// copied from KonqTreeViewItem::makeAccessString()