/*************************************************************************** arc_vfs.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * 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 #include #include #include #include // QT includes #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include #include // krusader includes #include "arc_vfs.h" #include "krpermhandler.h" #include "krarchandler.h" #include "../krusader.h" #include "../defaults.h" #include "../resources.h" #include "../Dialogs/krdialogs.h" #define MAX_FILES 500 //constructor arc_vfs::arc_vfs(TQString origin,TQString type,TQObject* panel,bool write): vfs(panel),arcFile(origin),changed(false),prefix(""),ignoreLines(0){ if ( type == "tarz" ) type = "-tgz"; // set the cursor to busy mode if (!quietMode) krApp->setCursor(KCursor::waitCursor()); // set the writable attribute isWritable = KRpermHandler::fileWriteable(origin); isWritable = ( write && isWritable ); vfs_type = vfs::ERROR; // create the temp dir.. tmpDir = krApp->getTempDir(); if( tmpDir.isEmpty() ){ error = true; return; } TQString password = TQString(); krConfig->setGroup("Archives"); // fill the command options if( type == "gzip" ){ cmd = KrServices::fullPathName ( "gzip" ); listCmd = "-l"; delCmd = ""; addCmd = KrServices::fullPathName ( "gzip" ) + " -c"; getCmd = "-dc"; ignoreLines = -1; isWritable = false; } if(type == "zip2"){ cmd = KrServices::fullPathName( "bzip2" ); listCmd = ""; delCmd = ""; addCmd = KrServices::fullPathName( "bzip2" )+ " -c"; getCmd = "-dc"; ignoreLines = -1; isWritable = false; } if(type == "-tar"){ cmd = KrServices::fullPathName( "tar" ); listCmd = " -tvf"; delCmd = cmd+" --delete -vf"; addCmd = cmd+" -uvf"; getCmd = " -xvf"; } if(type == "-tgz"){ cmd = KrServices::fullPathName( "tar" ); listCmd = " -tzvf"; delCmd = ""; addCmd = cmd+" -uvzf"; getCmd = " -xzvf"; isWritable = false; } if(type == "-tbz"){ cmd = KrServices::fullPathName( "tar" ); listCmd = " -tjvf"; delCmd = ""; addCmd = cmd+" -uvjf"; getCmd = " -xjvf"; isWritable = false; } if(type == "-zip"){ password = KRarcHandler::getPassword(arcFile,type); cmd = KrServices::fullPathName( "unzip" ); listCmd = "-ZTs "; TQString zipcmd = KrServices::fullPathName( "zip" ); delCmd = zipcmd+" -d"; addCmd = zipcmd+" -ry"; getCmd = " -o"; if( !password.isEmpty() ){ //listCmd = listCmd + " -P "+password; delCmd = delCmd + " -P "+password; addCmd = addCmd + " -P "+password; getCmd = getCmd + " -P "+password; } ignoreLines = 1; } // "-rpm" is used only to list the rpm - to extract files use "+rpm" if(type == "-rpm"){ //rpm can't handle files with " " in them so replace " " with "\ " arcFile.replace(TQRegExp(" "),"\\ "); cmd = KrServices::fullPathName( "rpm" ); listCmd = " --dump -lpq "; delCmd = ""; addCmd = ""; getCmd = ""; isWritable = false; } if( type == "+rpm" ){ // extract the cpio archive from the rpm KShellProcess rpm; rpm << "rpm2cpio"<<"\""+arcFile+"\""+" > "+tmpDir+"/contents.cpio"; rpm.start(TDEProcess::Block); arcFile = tmpDir+"/contents.cpio"; } if(type == "cpio" || type == "+rpm" ){ cmd = KrServices::fullPathName( "cpio" ); listCmd = "-tvF "; delCmd = ""; addCmd = ""; getCmd = " --force-local --no-absolute-filenames -ivdF"; isWritable = false; } if(type == "-rar"){ bool doRar = krConfig->readBoolEntry("Do Rar",_DoRar); cmd = KrServices::fullPathName( "unrar" ); listCmd = " -c- v "; delCmd = ""; addCmd = (doRar ? TQString(KrServices::fullPathName( "rar" ) + " -r a ") : TQString("")) ; getCmd = " x -y "; ignoreLines = 8; isWritable = (doRar && isWritable ); } getDirs(); // set the cursor to normal mode if (!quietMode) krApp->setCursor(KCursor::arrowCursor()); } // return the working dir TQString arc_vfs::vfs_workingDir(){ // get the path inside the archive TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); if(path.left(1) != "/") path = "/"+path; TQDir().mkdir(tmpDir+path); return tmpDir+path; } arc_vfs::~arc_vfs(){ // set the cursor to busy mode if (!quietMode) krApp->setCursor(KCursor::waitCursor()); // don't touch messed-up archives if(!error) repack(); // delete the temp dir KShellProcess proc; proc<<"rm"<<"-rf"<setCursor(KCursor::arrowCursor()); } bool arc_vfs::getDirs(){ if( !listCmd.isEmpty() ){ // write the temp file KShellProcess proc; proc << cmd << listCmd << "\""+arcFile+"\"" <<" > " << tmpDir+"/tempfilelist"; proc.start(TDEProcess::Block); if( !proc.normalExit() || !proc.exitStatus() == 0 ){ if (!quietMode) KMessageBox::error(krApp, i18n("Can't read %1. Archive " "might be corrupted!").arg(arcFile.mid(arcFile.findRev('/')+1))); error = true; return false; } // clear the dir list dirList.clear(); // prepare the first dir entry - the "" entry arc_dir *tempdir = new arc_dir(""); vfs_filesP = &(tempdir->entries); dirList.append(tempdir); // parse the temp file TQFile temp(tmpDir+"/tempfilelist"); temp.open(IO_ReadOnly); char buf[1000]; TQString line; if(vfs_type == "gzip" || vfs_type == "-zip" ) temp.readLine(line,10000); // skip the first line - it's garbage if( vfs_type == "-rar" ){ while(temp.readLine(line,10000) != -1) if ( line.contains("----------") ) break; } while(temp.readLine(buf,1000) != -1){ line = TQString::fromLocal8Bit(buf); if ( line.contains("----------") ) break; parseLine(line.stripWhiteSpace(),&temp); } temp.close(); TQDir().remove(tmpDir+"/tempfilelist"); } else { // bzip2 // clear the dir list dirList.clear(); // prepare the first dir entry - the "" entry arc_dir *tempdir = new arc_dir(""); vfs_filesP = &(tempdir->entries); dirList.append(tempdir); parseLine("",0); } return true; } // copy a file to the vfs (physical) void arc_vfs::vfs_addFiles(KURL::List *fileUrls,TDEIO::CopyJob::CopyMode mode,TQObject* toNotify,TQString dir, PreserveMode /*pmode*/ ){ if ( addCmd.isEmpty() ) return; // get the path inside the archive TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); path = path+"/"; if(dir != "" ) dir = "/"+dir; if(path.left(1) != "/") path = "/"+path; // make sure the destination exist for( int i=0; i >= 0 ; i= TQString(tmpDir+path+dir).find('/',i+1) ){ TQDir().mkdir(TQString(tmpDir+path+dir).left(i)); } changed = true; //rescan the archive KURL dest; dest.setPath(tmpDir+path+dir); TDEIO::Job* job = new TDEIO::CopyJob(*fileUrls,dest,mode,false,true); connect(job,TQT_SIGNAL(result(TDEIO::Job*)),this,TQT_SLOT(vfs_refresh(TDEIO::Job*)) ); if(mode == TDEIO::CopyJob::Move) // notify the other panel connect(job,TQT_SIGNAL(result(TDEIO::Job*)),toNotify,TQT_SLOT(vfs_refresh(TDEIO::Job*)) ); } // remove a file from the vfs (physical) void arc_vfs::vfs_delFiles(TQStringList *fileNames){ if ( delCmd.isEmpty() ) return; // if we move to trash - just extract files and move them to trash - // the repack() will delete them for us krConfig->setGroup("General"); if( krConfig->readBoolEntry("Move To Trash",_MoveToTrash) ) { KURL::List* filesUrls = vfs_getFiles(fileNames); // extract changed = true; TDEIO::Job *job = new TDEIO::CopyJob(*filesUrls,TDEGlobalSettings::trashPath(),TDEIO::CopyJob::Move,false,true ); connect(job,TQT_SIGNAL(result(TDEIO::Job*)),this,TQT_SLOT(vfs_refresh(TDEIO::Job*))); } // else we have to delete the files from both the archive and the temp dir else { // change dir to the temp dir TQString save = getcwd(0,0); chdir(tmpDir.local8Bit()); TQStringList files; TDEIO::filesize_t totalSizeVal = 0; unsigned long totalFilesVal = 0; // names -> urls for(TQStringList::Iterator name = fileNames->begin(); name != fileNames->end(); ++name ) processName(*name,&files,&totalSizeVal,&totalFilesVal); KShellProcess proc1 , proc2; krApp->startWaiting(i18n("Deleting Files..."),files.count()+ignoreLines); connect(&proc1,TQT_SIGNAL(receivedStdout(TDEProcess*,char*,int)), krApp, TQT_SLOT(incProgress(TDEProcess*,char*,int)) ); proc1 << delCmd << "\""+arcFile+"\""; proc2 << "rm -rf"; for(unsigned int i =0; i < files.count(); ){ proc1 << (prefix+*files.at(i)); proc2 << tmpDir+"/"+(*files.at(i)); extFiles.remove(*files.at(i++)); if ( i%MAX_FILES==0 || i==files.count() ){ proc1.start(TDEProcess::NotifyOnExit,TDEProcess::AllOutput); proc2.start(); while( proc1.isRunning() || proc2.isRunning() ) tqApp->processEvents(); // busy wait - need to find something better... proc1.clearArguments() ; proc2.clearArguments(); proc1 << delCmd << "\""+arcFile+"\""; proc2 << "rm -rf"; } } krApp->stopWait(); changed = true; chdir (save.local8Bit()); vfs_refresh(vfs_origin); } } // return a path to the file TQString arc_vfs::vfs_getFile(TQString name){ // get the current file path TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); if(path.left(1)=="/") path.remove(0,1); if(path != "") path = path+"/"; TQStringList temp(name); vfs_getFiles(&temp); return tmpDir+"/"+path+name; } KURL::List* arc_vfs::vfs_getFiles(TQStringList* names){ KURL url; KURL::List* urls = new KURL::List(); // get the current file path TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); if(path.left(1)=="/") path.remove(0,1); if(path != "") path = path+"/"; // change dir to the temp dir TQString save = getcwd(0,0); chdir(tmpDir.local8Bit()); // names -> urls TQStringList files; TDEIO::filesize_t totalSize = 0; unsigned long totalFiles = 0; for(TQStringList::Iterator name = names->begin(); name != names->end(); ++name ){ processName(*name,&files,&totalSize,&totalFiles); url.setPath(tmpDir+"/"+path+(*name)); urls->append(url); } // check the urls for unpacked files and directories for(TQStringList::Iterator file = files.begin(); file != files.end(); ++file ){ if ( (*file).right(1)=="/" ){ TQDir(tmpDir).mkdir(*file); if( vfs_type == "-rar" ) file = files.remove(file--); } // don't unpack the same file twice else if( extFiles.contains(*file) ){ file = files.remove(file--); } } // unpack ( if needed ) if ( files.count() > 0 ){ krApp->startWaiting(i18n("Unpacking Files"),files.count()+ignoreLines); KShellProcess proc; connect(&proc,TQT_SIGNAL(receivedStdout(TDEProcess*,char*,int)), krApp, TQT_SLOT(incProgress(TDEProcess*,char*,int)) ); proc << cmd << getCmd << "\""+arcFile+"\""; if( vfs_type == "gzip" || vfs_type == "zip2" ) proc << ">"; for(unsigned int i=0 ; i < files.count() ; ){ proc << (prefix+*files.at(i++)); if ( i%MAX_FILES==0 || i==files.count() ){ proc.start(TDEProcess::NotifyOnExit,TDEProcess::AllOutput); while( proc.isRunning() ) tqApp->processEvents(); proc.clearArguments(); proc << cmd << getCmd << "\""+arcFile+"\""; } } getExtFiles(); // this will update the extFiles list. krApp->stopWait(); } // restore dir chdir(save.local8Bit()); return urls; } // make dir void arc_vfs::vfs_mkdir(TQString name){ TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); if(path.left(1)=="/") path.remove(0,1); if(path != "") path = path+"/"; TQDir(tmpDir).mkdir(path+name); changed = true; //rescan the archive vfs_refresh(vfs_origin); } // rename file void arc_vfs::vfs_rename(TQString fileName,TQString newName){ KURL::List temp; temp.append(vfs_getFile(fileName)); TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); if(path.left(1)=="/") path.remove(0,1); if(path != "") path = path+"/"; TQDir(tmpDir).mkdir(path); changed = true; //rescan the archive KURL dest; dest.setPath(tmpDir+path+"/"+newName); TDEIO::Job* job = new TDEIO::CopyJob(temp,dest,TDEIO::CopyJob::Move,false,false); connect(job,TQT_SIGNAL(result(TDEIO::Job*)),this,TQT_SLOT(vfs_refresh(TDEIO::Job*)) ); } bool arc_vfs::vfs_refresh(TQString origin){ if ( error ) return false; if ( changed || origin == vfs_origin ){ repack(); // repack dirs only if needed if ( !getDirs() ){ if (!quietMode) emit startUpdate(); return true; } changed = false; } vfs_origin = origin; // get the directory... TQString path = origin.right((origin.length()-origin.findRev('\\'))-1); if(path.left(1) =="/") path.remove(0,1); vfs_filesP = findDir(path); if (!quietMode) emit startUpdate(); return true; } // service functions TQString arc_vfs::nextWord(TQString &s,char d) { s=s.stripWhiteSpace(); int j=s.find(d,0); TQString temp=s.left(j); // find the leftmost word. s.remove(0,j); return temp; } void arc_vfs::getFilesToPack(TQStringList* filesToPack,TQString dir_name){ bool newDir = false; vfileDict *vfs_filesP_backup = vfs_filesP; // save vfs_filesP // init all the diffrent lists (and list pointers); vfs_filesP=findDir(dir_name); if ( vfs_filesP == 0) newDir = true; if(dir_name != "") dir_name = dir_name+"/"; DIR* dir = opendir(tmpDir.local8Bit()+"/"+dir_name.local8Bit()); if(!dir) return ; struct dirent* dirEnt; TQString name; KDE_struct_stat stat_p; while( (dirEnt=readdir(dir)) != NULL ){ name = dirEnt->d_name; if ( name == ".." || name == "." ) continue; if( KDE_lstat(tmpDir.local8Bit()+"/"+dir_name.local8Bit()+name.local8Bit(),&stat_p) ) continue; extFile temp(dir_name+name,stat_p.st_mtime,stat_p.st_size); // add to the list file that are diffrent than the ones packed if( S_ISDIR(stat_p.st_mode) ){ // recurse on all sub dirs if( !findDir(dir_name+name) ){ // add to the list only new && empty dirs if( newDir && TQDir(dir_name+name).entryList(TQDir::All | TQDir::AccessMask).count() <= 2 ) filesToPack->append( dir_name+name); } getFilesToPack(filesToPack,dir_name+name); continue; } // if the file don't exist add it to the archive and to the extFiles if( newDir || !extFiles.contains( dir_name+name ) ){ filesToPack->append( dir_name+name ); extFiles.append( temp ); } // else if the file exist but was modified - repack it; else if( !extFiles.contains( temp ) ){ filesToPack->append( dir_name+name ); extFiles.remove( dir_name+name ); extFiles.append( temp ); } } vfs_filesP = vfs_filesP_backup; // restore vfs_filesP } void arc_vfs::getFilesToDelete(TQStringList* filesToDelete,TQString){ // sync the extFiles - and find out which files were deleted TQString file; for(unsigned int i=0 ; iappend( (*extFiles.at(i)).url ); extFiles.remove(extFiles.at(i)); } else ++i; } } void arc_vfs::getExtFiles(TQString dir_name){ DIR* dir = opendir(tmpDir.local8Bit()+"/"+dir_name.local8Bit()); if(!dir){ kdWarning() << "faild to opendir(): " << tmpDir.local8Bit()+"/"+dir_name.local8Bit() << endl; return ; } if( dir_name != "") dir_name = dir_name+"/"; struct dirent* dirEnt; TQString name; KDE_struct_stat stat_p; while( (dirEnt=readdir(dir)) != NULL ){ name = dirEnt->d_name; if ( name == ".." || name == "." ) continue; if( KDE_lstat(tmpDir.local8Bit()+"/"+dir_name.local8Bit()+name.local8Bit(),&stat_p) ) continue; extFile temp(dir_name+name,stat_p.st_mtime,stat_p.st_size); // recurse on all sub dirs if( S_ISDIR(stat_p.st_mode) ){ getExtFiles(dir_name+name); } // if the file is not in extFiles - it is newly extracted. // note: getFilesToPack() updates time + size ! else if( !extFiles.contains( dir_name+name ) ){ extFiles.append( temp ); } } } void arc_vfs::repack(){ TQString save = getcwd(0,0); chdir(tmpDir.local8Bit()); // delete from the archive files that were unpacked and deleted if( vfs_isWritable() ){ TQStringList filesToDelete; getFilesToDelete(&filesToDelete); if( !filesToDelete.isEmpty() ){ KShellProcess delProc; krApp->startWaiting(i18n("Deleting Files..."),filesToDelete.count()+ignoreLines); connect(&delProc,TQT_SIGNAL(receivedStdout(TDEProcess*,char*,int)), krApp, TQT_SLOT(incProgress(TDEProcess*,char*,int)) ); delProc << delCmd << "\""+arcFile+"\""; for( unsigned int i=0 ; i < filesToDelete.count() ;){ delProc << (*filesToDelete.at(i++)); if( i%MAX_FILES==0 || i==filesToDelete.count() ){ delProc.start(TDEProcess::NotifyOnExit,TDEProcess::AllOutput); while( delProc.isRunning() ) tqApp->processEvents(); delProc.clearArguments(); delProc << delCmd << "\""+arcFile+"\""; } } krApp->stopWait(); } } // finaly repack tmpDir if( vfs_isWritable() || vfs_type=="gzip" || vfs_type=="zip2" ){ TQStringList filesToPack; getFilesToPack(&filesToPack); if( !filesToPack.isEmpty() ){ KShellProcess addProc; krApp->startWaiting(i18n("Repacking..."),filesToPack.count()+ignoreLines); connect(&addProc,TQT_SIGNAL(receivedStdout(TDEProcess*,char*,int)), krApp, TQT_SLOT(incProgress(TDEProcess*,char*,int)) ); if( vfs_type=="gzip" || vfs_type=="zip2" ){ addProc << addCmd << *filesToPack.at(0)<< ">" << "\""+arcFile+"\""; addProc.start(TDEProcess::NotifyOnExit); while( addProc.isRunning() ) tqApp->processEvents(); } else { addProc << addCmd << "\""+arcFile+"\""; for( unsigned int i=0 ; iprocessEvents(); // busy wait - need to find something better... addProc.clearArguments(); addProc << addCmd << "\""+arcFile+"\""; } } } krApp->stopWait(); } } chdir(save.local8Bit()); } vfileDict* arc_vfs::findDir(TQString name){ for(arc_dir* temp = dirList.first();temp != 0 ; temp = dirList.next()){ if(temp->name == name) return &(temp->entries); } return 0; } arc_vfs::arc_dir* arc_vfs::findArcDir(TQString name){ for(arc_dir* temp = dirList.first();temp != 0 ; temp = dirList.next()){ if(temp->name == name) return temp; } return 0; } TQString arc_vfs::changeDir(TQString name){ if(name.left(2) == "./") { prefix = "./"; name.remove(0,2); } if(!name.contains('/')){ vfs_filesP = findDir(""); return name; } // seperate the path from the name TQString path = name.left(name.findRev('/')); name = name.mid(name.findRev('/')+1); // see if the path exists if ((vfs_filesP=findDir(path)) == 0){ //create a new dir entry TQString Pname = path.mid(path.findRev('/')+1); if(Pname.isEmpty()) return name; TQString tempName = arcFile; TQFileInfo qfi(tempName.replace(TQRegExp("\\"),"")); vfile* vf=new vfile(Pname,0,"drwxr-xr-x",qfi.lastModified().toTime_t(),false, qfi.owner(),qfi.group(),"inode/directory","",0 ); // add dirs if needed changeDir(path); vfile* vf2 = vfs_search(Pname); if(vf2 != 0) vfs_removeFromList(vf2); vfs_addToList(vf); // add a new arc_dir dirList.append(new arc_dir(path)); vfs_filesP = findDir(path); } return name; } // calculate space void arc_vfs::vfs_calcSpace(TQString name ,TDEIO::filesize_t *totalSize,unsigned long *totalFiles,unsigned long *totalDirs,bool* stop){ if ( *stop ) return; vfile* vf = vfs_search(name); // get the path inside the archive TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); path = path+"/"; if(path.left(1) == "/") path.remove(0,1); if( !vf->vfile_isDir() ){ // single files are simple :) ++(*totalFiles); (*totalSize) += vf->vfile_getSize(); } else { // handle directories : ( ++(*totalDirs); TQString origin_backup = vfs_origin; // backup the vfs origin vfs_origin = vfs_origin+"/"+name; vfileDict* vfs_filesP_backup = vfs_filesP; // backup the vfs_filesP vfs_filesP = findDir(path+name); // process all the files in the directory. for( vf = vfs_getFirstFile(); vf != 0; vf = vfs_getNextFile() ){ if (*stop) return; vfs_calcSpace(vf->vfile_getName(),totalSize,totalFiles,totalDirs,stop); } vfs_origin = origin_backup; // restore origin vfs_filesP = vfs_filesP_backup; // restore vfs_filesP } } void arc_vfs::processName(const TQString& name, TQStringList *urls,TDEIO::filesize_t *totalSize,unsigned long *totalFiles ){ vfile* vf = vfs_search(name); if ( vf == 0 ) return; // get the path inside the archive TQString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1); path = path+"/"; if(path.left(1) == "/") path.remove(0,1); if( !vf->vfile_isDir() || vf->vfile_isSymLink() ){ // single files are simple :) ++(*totalFiles); (*totalSize) += vf->vfile_getSize(); urls->append(path+name); } else { // handle directories : ( urls->append(path+name+"/"); TQString origin_backup = vfs_origin; // backup the vfs origin vfs_origin = vfs_origin+"/"+name; vfileDict* vfs_filesP_backup = vfs_filesP; // backup the vfs_filesP vfs_filesP = findDir(path+name); // process all the files in the directory. for( vf = vfs_getFirstFile(); vf != 0; vf = vfs_getNextFile() ) processName(vf->vfile_getName(),urls,totalSize,totalFiles); vfs_origin = origin_backup; // restore origin vfs_filesP = vfs_filesP_backup; // restore vfs_filesP } } void arc_vfs::parseLine(TQString line, TQFile* temp){ TQString name; TDEIO::filesize_t size = 0; TQString perm; TQFileInfo qfi(arcFile); time_t mtime = qfi.lastModified().toTime_t(); bool link = false; uid_t owner = getuid(); gid_t group = getgid(); TQString dest = ""; mode_t mode = 0; // parse gziped files if(vfs_type == "gzip"){ KDE_struct_stat stat_p; KDE_stat(arcFile.local8Bit(),&stat_p); nextWord(line); size = nextWord(line).toLong(); nextWord(line); name = nextWord(line,'\n'); if(name.contains('/')) name = name.mid(name.findRev('/')+1,name.length()); perm = KRpermHandler::mode2TQString(stat_p.st_mode) ; owner = KRpermHandler::user2uid(qfi.owner()); group = KRpermHandler::group2gid(qfi.group()); mode = stat_p.st_mode; } // parse bzip2ed files if( vfs_type == "zip2" ){ KDE_struct_stat stat_p; KDE_stat(arcFile.local8Bit(),&stat_p); name = qfi.fileName(); name = name.left(name.findRev('.')); //long size = qfi.size(); perm = KRpermHandler::mode2TQString(stat_p.st_mode) ; owner = KRpermHandler::user2uid(qfi.owner()); group = KRpermHandler::group2gid(qfi.group()); mode = stat_p.st_mode; } // parse tar files if(vfs_type == "-tar" || vfs_type == "-tbz" || vfs_type == "-tgz" ){ perm = nextWord(line); TQString temp = nextWord(line); owner = temp.left(temp.findRev('/')).toInt(); group = temp.mid(temp.find('/')+1,temp.length()).toInt(); size = nextWord(line).toLong(); temp = nextWord(line); name = nextWord(line,'\n'); if (name.startsWith("/")) // fix full-paths problem in tar (thanks to Heiner!) name.remove(0, 1); if( name.contains(" -> ") ){ link = true; dest = name.mid(name.find(" -> ")+4); name = name.left(name.find(" -> ")); } } // parse zipped files if(vfs_type == "-zip"){ perm = nextWord(line); if(perm.length() != 10) perm = (perm.at(0)=='d')? "drwxr-xr-x" : "-rw-r--r--" ; if (nextWord(line).contains("file")) return; nextWord(line); size = nextWord(line).toLong(); nextWord(line);nextWord(line); TQString temp = nextWord(line); name = nextWord(line,'\n'); } // parse cpio packages if(vfs_type == "cpio" || vfs_type == "+rpm"){ perm = nextWord(line); nextWord(line);nextWord(line);nextWord(line); size = nextWord(line).toLong(); nextWord(line);nextWord(line);nextWord(line); TQString tempName = arcFile; TQFileInfo qfi(tempName.replace(TQRegExp("\\"),"")); name = nextWord(line,'\n'); if ( name.left(1) == "/" ) name.remove(0,1); if( name.contains(" -> ") ){ link = true; dest = name.mid(name.find(" -> ")+4); name = name.left(name.find(" -> ")); } } // parse rared files if(vfs_type == "-rar"){ name = nextWord(line,'\n'); temp->readLine(line,10000); size = nextWord(line).toLong(); nextWord(line); nextWord(line); perm = nextWord(line); if(perm.length() != 10) perm = (perm.at(1)=='D')? "drwxr-xr-x" : "-rw-r--r--" ; } // parse rpm packages if(vfs_type == "-rpm"){ name = nextWord(line); if ( name.left(1) == "/" ) name.remove(0,1); size = nextWord(line).toLong(); mtime = nextWord(line).toLong(); nextWord(line); perm = KRpermHandler::mode2TQString(nextWord(line).toLong()); perm = (perm.at(0)=='d')? "drwxr-xr-x" : "-rw-r--r--" ; } if ( perm[0]=='d' && name.right(1) != "/" ) name = name+"/"; name = changeDir(name); if(name.length() < 1) return; TQString mime = KMimeType::findByURL( "/"+name,0,true,true)->name(); vfile* vf=new vfile(name,size,perm,mtime,link,owner,group,mime,dest,mode); vfile* vf2 = vfs_search(name); if(vf2 != 0) vfs_removeFromList(vf2); vfs_addToList(vf); } #include "arc_vfs.moc"