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()