Logo Search packages:      
Sourcecode: karchiver version File versions  Download package

csit.cpp

/***************************************************************************
                          czip.cpp  -  description
                             -------------------
    begin                : Sat Dec 2 2000
    copyright            : (C) 2000 by Eric Coquelle
    email                : coquelle@caramail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "csit.h"

#include <kdebug.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>


CSit::CSit(){
  CArchive();
  
  connect(&processread,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOut(KProcess*,char*,int)));
  connect(&processread,SIGNAL(processExited (KProcess*)),this,SLOT(displayExtractedFiles(KProcess*)));
  connect(&processextract,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOutExtract(KProcess*,char*,int)));
  connect(&processextract,SIGNAL(processExited (KProcess*)),this,SLOT(endProcess(KProcess*)));
  connect(&processextract, SIGNAL(receivedStderr(KProcess *, char *, int)),this, SLOT(haveSdtErrExtract(KProcess*,char*,int)));
  connect(&processadd,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOutExtract(KProcess*,char*,int)));

    
  list->setColumnText(4, i18n("Owner"));
  list->setColumnText(5, i18n("Ratio"));
   
  format="sit5";
}

CSit::~CSit(){
archivePassword="";
}

void CSit::prepareTmpDir()
{
  QString directory;
  directory.sprintf("karchivertmp.%d/", getpid());
  tmpdir = locateLocal( "tmp", directory );
  directory.sprintf("karchivertmp.%d/extract-sit/", getpid());
  tmpdirsit = locateLocal( "tmp", directory );
  if(!tmpdirsit.isNull())
  {
    /*if(!tmpdirsit.endsWith("/"))
    tmpdirsit=tmpdirsit+"/";*/
    KProcess removefiles;
    removefiles << "rm" << "-rf" << tmpdirsit;//+"*";
    removefiles.start(KProcess::Block);
    tmpdirsit = locateLocal( "tmp", directory );
  }
}

/** Get recursively all files contained in the directory @param d */
00065 QStringList CSit::getAllFiles(QDir d)
{
  kdDebug()<<QString("CSit::Getting all files from %1").arg(d.path())<<endl;
  QStringList listoffilestoview;
  QStringList filesandsubdirs;
  QString basedir=d.path()+"/";
  filesandsubdirs=d.entryList(QDir::Dirs);
  
  for ( QStringList::Iterator it = filesandsubdirs.begin(); it != filesandsubdirs.end(); ++it ) {
    kdDebug()<<QString("Looking in %1").arg(basedir + *it)<<endl;
    if((*it!=".")&&(*it!=".."))
      listoffilestoview+=getAllFiles(QDir(basedir + *it));
  }
  filesandsubdirs=d.entryList(QDir::Files);
  for ( QStringList::Iterator it = filesandsubdirs.begin(); it != filesandsubdirs.end(); ++it ) {
    listoffilestoview.append(basedir + *it);
  }
  return listoffilestoview;
}

/** this method will launch the right compressor
      to list the file contents
      It will then launch the right method to display
      the content in the listview */
00089 void CSit::displayArchiveContent(){

  initializeReadingArchive();

  prepareTmpDir();
  KProcess copyproc;
  copyproc.clearArguments();
  copyproc << "ln" << "-sf" << archiveName << tmpdir;//unstuff can only extract in current directory
  copyproc.start(KProcess::Block);
  QDir::setCurrent(tmpdir);
  
  processread.clearArguments();
  processread << "unstuff" << "-q";
  
  kdDebug()<<QString("CSit::displayArchiveContent: Extracting %2 in %1").arg(tmpdirsit).arg(QFileInfo(archiveName).fileName())<<endl;
  
  if(!archivePassword.isEmpty()) 
    processextract << archivePassword; 
  processread << "-d=extract-sit"; //-d is buggy, cannot extract to absolute pathes..
  processread << QFileInfo(archiveName).fileName();
  processread.start(KProcess::NotifyOnExit,KProcess::AllOutput);
}

void CSit::displayExtractedFiles(KProcess*)
{
  CListViewItem* elementListe=NULL;
  
  kdDebug()<<QString("CSit::displayExtractedFiles: removing %1 from tmpdirsit").arg(tmpdir+QFileInfo(archiveName).fileName())<<endl;
  KProcess removeproc;
  removeproc.clearArguments();
  removeproc << "rm" << "-f" << tmpdir+QFileInfo(archiveName).fileName();
  removeproc.start(KProcess::Block);
  
  QStringList listoffiles=getAllFiles( QDir(tmpdirsit) );
  QString basedir;
  QFileInfo fileinfo;
  QDateTime date;
  
  for(QStringList::Iterator it=listoffiles.begin(); it!=listoffiles.end(); ++it)
  {
    kdDebug()<<QString("CSit::displayExtractedFiles: processing %1").arg(*it)<<endl;
    fileinfo.setFile(*it);
    basedir=fileinfo.dirPath()+"/";
    basedir=basedir.remove(tmpdirsit);
    date=fileinfo.created();
    
    elementListe=new CListViewItem(list, fileinfo.fileName(), QString::number(fileinfo.size()) , date.toString("hh:mm"),getLocalizedDate( date.date() ), fileinfo.owner(), "", basedir);

    setIcon(fileinfo.fileName(), "", elementListe);
    elementListe->widthChanged();
  }
  
  
  emit archiveReadEnded();
}

/** we recive some informations through the standard
output of the process */
00147 void CSit::haveSdtOut(KProcess *, char *buffer, int length){
}

/** we recive some informations through the error
      * output of the process */
00152 void CSit::haveSdtErrExtract(KProcess *prc, char *buffer, int length){
  buffer[length]=0;

  if (strstr(buffer,"incorrect password")) {
    KMessageBox::error(NULL, i18n("An error occurred during extraction: \n The archive is password protected and the given password is wrong.\nPlease choose 'Archive->Set Password', change the password and try it again."));
    return;
  }
  CArchive::haveSdtErrExtract(prc, buffer, length);
}


/** we recive some informations through the standard
      * output of the process */
00165 void CSit::haveSdtOutExtract(KProcess *, char *, int ){
      counter++;
      if(counter%2==0)
            progressbar->setProgress(progressbar->progress()+ 1 );

}

/** The current process ended */
00173 void CSit::endProcess(KProcess*){
  kdDebug()<<("Process ENDED\n");

  emit(archiveReadEnded());
}

/** Upon the kind of archive, choose the right
      *uncompressor and extract all or some files
      *@toutextraire = 9: extract to karchiveur's temp directory (for viewing)
      *@toutextraire = 1: extract all selected files
      */
00184 void CSit::extractArchive(QString & extractpath, int extractall, QString &filetoextract){
  QStringList listsubdir;

  errors.clear();
  counter=0;
  progressbar->reset();

  QDir d;
  d.setCurrent(tmpdirsit);
  //Unstuff's -d option don't work, so just copy the files...
  processextract.clearArguments();
  processextract << "cp" << "--parents";

  kdDebug()<<QString("CSit::extractArchive %1 to %2").arg(archiveName).arg(extractpath)<<endl;
  
  if((extractall!=EXTRACTONE)&&(extractall!=EXTRACTONE_AND_BLOCK)&&(!checkFiles(extractpath, extractall)))
  {
    endProcess(NULL);
    return;
  }
  else if(extractall==EXTRACTONE_AND_BLOCK)
  {
    //We want to view (and so extract) only one file. So we just add this file to the tar or unzip
    //command.
    processextract << filetoextract;
    processextract << extractpath;
    if(processextract.start(KProcess::Block)==FALSE)
      kdDebug()<<("\n*PB PROCESS*\n");
  }
  else if(extractall==EXTRACTONE)
  {
    //We want to view (and so extract) only one file. So we just add this file to the tar or unzip
    //command.
    processextract << filetoextract;
    processextract << extractpath;
    if(processextract.start(KProcess::NotifyOnExit)==FALSE)
      kdDebug()<<("\n*PB PROCESS*\n");
  }
  else if(extractall!=EXTRACTONE_AND_BLOCK)
  {
    //We extract through the Stdout to have a progress indicator
    processextract << extractpath;
    if(processextract.start(KProcess::NotifyOnExit,KProcess::AllOutput)==FALSE)
      kdDebug()<<("\n*PB PROCESS*\n");
  }
  counter=0;
}

/** delete @param filestodelete from current archive */
00233 void CSit::removeFilesFromArchive( QStringList filestodelete ){
  KProcess move;
  QDir d;
  d.setCurrent(tmpdirsit);

  kdDebug()<<QString("In CSit::removeFilesFromArchive %1").arg(archiveName)<<endl;
  
  //Backup archive for safety, as stuff don't support adding files to an existing archive...
  kdDebug()<<QString("Moving %1 to %2").arg(archiveName).arg(tmpdir)<<endl;
  move.clearArguments();
  move << "mv" << "-f" << archiveName << tmpdir;
  move.start(KProcess::Block);
  
  processadd.clearArguments();
  processadd << "stuff";
  processadd << "--quiet";
  if(!archivePassword.isEmpty())
    processadd  << "--password="+archivePassword;
  processadd << "--format="+format;
  processadd << "--name="+archiveName;

  for (QStringList::Iterator f = filestodelete.begin(); f!=filestodelete.end(); ++f )
  {
    QFile::remove( tmpdirsit + *f );
    kdDebug()<<QString("Erasing %1").arg(tmpdirsit + *f)<<endl;
  }

  QStringList files=d.entryList();
  for (QStringList::Iterator f = files.begin(); f!=files.end(); ++f )
  {
    if((*f != ".")&&(*f != ".."))
    {
      processadd << *f;
      kdDebug()<<QString("Appending %1 in dir %2 to archive %3").arg(*f).arg(tmpdirsit).arg(archiveName)<<endl;
    }
  }
  if(processadd.start(KProcess::Block)==false)
  {
    move.clearArguments();
    move << "mv" << tmpdir+QFileInfo(archiveName).fileName() << archiveName;
    move.start(KProcess::Block);
  }
  else
  {
    move.clearArguments();
    move << "rm" << "-f" << tmpdir+QFileInfo(archiveName).fileName();
    move.start(KProcess::Block);
  }

  emit archiveReadEnded();
}

/** Add some files to the archive
@param filestoadd : list of files to add
@param removeoriginalfiles : remove or not those files from disk
@param action : 0=mode append and replace files, 1=mode update files
@param relativepath : if !NULL, include only filenames, without their base path */
00290 void CSit::addFilesToArchive( QStringList filestoadd, bool removeoriginalfiles, int action, QString relativepath)
{
   KProcess processcopy;
   QString s;
   kdDebug()<<QString("CSit::addFilesToArchive %1, RelativePath=%2").arg(archiveName).arg(relativepath)<<endl;
      if(relativepath!=NULL)
   QDir::setCurrent(relativepath);

    for (QStringList::Iterator f = filestoadd.begin(); f!=filestoadd.end(); ++f )
    {
      s=*f;
      if(s.endsWith("/") )
        s.truncate(s.length()-1);
      if(s.startsWith("file:"))
        s.remove(0,5);
      kdDebug()<<QString("Appending %1 to Sit archive %2").arg(s).arg(archiveName)<<endl;
      processcopy.clearArguments();
      processcopy << "cp" << "--parents" << s << tmpdirsit;
      processcopy.start(KProcess::Block);
    }
   QStringList tmp;
   //stuff is unable to add or remove files from an archive, so copy all files to tmpdirsit and create a new archive...
   removeFilesFromArchive(tmp);
}

/** Create a sit archive
@param  nameofarchive: the name of the zip archive
@param param: list of files to add
@param relativepath: include only filenames, without their path */
00319 void CSit::createArchive(QString nameofarchive, QStringList filestoadd, QString relativepath) {
      QString str;

      archiveName=nameofarchive;
      prepareTmpDir();
      kdDebug()<<QString("BeginCreationSit*%1*%2*").arg(nameofarchive).arg(relativepath)<<endl;
      addFilesToArchive(filestoadd, false, 0,relativepath);
}

/** Returns true if archive type supports passwords */
00329 bool CSit::supportPassword(){
 return true;
}

CHqx::CHqx()
{
  CArchive();

  connect(&processread,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOut(KProcess*,char*,int)));
  connect(&processread,SIGNAL(processExited (KProcess*)),this,SLOT(displayExtractedFiles(KProcess*)));
  connect(&processextract,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOutExtract(KProcess*,char*,int)));
  connect(&processextract,SIGNAL(processExited (KProcess*)),this,SLOT(endProcess(KProcess*)));
  connect(&processextract, SIGNAL(receivedStderr(KProcess *, char *, int)),this, SLOT(haveSdtErrExtract(KProcess*,char*,int)));
  connect(&processadd,SIGNAL(receivedStdout(KProcess*, char*, int)),this,SLOT(haveSdtOutExtract(KProcess*,char*,int)));
  connect(&processadd,SIGNAL(processExited (KProcess*)),this,SLOT(endProcess(KProcess*)));

    
  list->setColumnText(4, i18n("Packed"));
  list->setColumnText(5, i18n("Ratio"));

  format="hqx";
}

#include "csit.moc"

Generated by  Doxygen 1.6.0   Back to index