arc_vfs.cpp

来自「LINUX 下, 以 QT/KDE 写的档案管理员」· C++ 代码 · 共 867 行 · 第 1/2 页

CPP
867
字号
	temp.append(vfs_getFile(fileName));  QString path = vfs_origin.right((vfs_origin.length()-vfs_origin.findRev('\\'))-1);  if(path.left(1)=="/") path.remove(0,1);  if(path != "") path = path+"/";  QDir(tmpDir).mkdir(path);  changed = true; //rescan the archive	KURL dest;	dest.setPath(tmpDir+path+"/"+newName);  KIO::Job* job = new KIO::CopyJob(temp,dest,KIO::CopyJob::Move,false,false);  connect(job,SIGNAL(result(KIO::Job*)),this,SLOT(vfs_refresh(KIO::Job*)) );}bool arc_vfs::vfs_refresh(QString 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...  QString 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 functionsQString arc_vfs::nextWord(QString &s,char d) {  s=s.stripWhiteSpace();  int j=s.find(d,0);  QString temp=s.left(j); // find the leftmost word.  s.remove(0,j);  return temp;}void arc_vfs::getFilesToPack(QStringList* filesToPack,QString 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+"/"; 	register DIR* dir = opendir(tmpDir.local8Bit()+"/"+dir_name.local8Bit());  if(!dir) return ;	register struct dirent* dirEnt;  QString 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 && QDir(dir_name+name).entryList(QDir::All | QDir::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(QStringList* filesToDelete,QString){	// sync the extFiles - and find out which files were deleted	QString file;	for(unsigned int i=0 ; i<extFiles.count(); ){		file = tmpDir+"/"+(*extFiles.at(i)).url;		if( !KRpermHandler::fileExist(file) ){  		filesToDelete->append( (*extFiles.at(i)).url );    	extFiles.remove(extFiles.at(i));   	}		else ++i;  }}void arc_vfs::getExtFiles(QString dir_name){	register 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+"/";		register struct dirent* dirEnt;  QString 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(){  QString save = getcwd(0,0);  chdir(tmpDir.local8Bit());	  // delete from the archive files that were unpacked and deleted	if( vfs_isWritable() ){		QStringList filesToDelete;		getFilesToDelete(&filesToDelete);		if( !filesToDelete.isEmpty() ){			KShellProcess delProc;  		krApp->startWaiting(i18n("Deleting Files..."),filesToDelete.count()+ignoreLines);	 		connect(&delProc,SIGNAL(receivedStdout(KProcess*,char*,int)),               krApp, SLOT(incProgress(KProcess*,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(KProcess::NotifyOnExit,KProcess::AllOutput);    			while( delProc.isRunning() )  qApp->processEvents();					delProc.clearArguments();		    	delProc << delCmd << "\""+arcFile+"\"";  			}			}  		krApp->stopWait();		}	}  // finaly repack tmpDir  if( vfs_isWritable() || vfs_type=="gzip" || vfs_type=="zip2" ){    QStringList filesToPack;		getFilesToPack(&filesToPack);		if( !filesToPack.isEmpty() ){			KShellProcess addProc;			krApp->startWaiting(i18n("Repacking..."),filesToPack.count()+ignoreLines);    	connect(&addProc,SIGNAL(receivedStdout(KProcess*,char*,int)),            krApp, SLOT(incProgress(KProcess*,char*,int)) );			if( vfs_type=="gzip" || vfs_type=="zip2" ){      	addProc << addCmd << *filesToPack.at(0)<< ">" << "\""+arcFile+"\"";				addProc.start(KProcess::NotifyOnExit);      	while( addProc.isRunning() ) qApp->processEvents();     	}    	else {				addProc << addCmd << "\""+arcFile+"\"";    		for( unsigned int i=0 ; i<filesToPack.count(); ){      		addProc << "\""+prefix+(*filesToPack.at(i++))+"\"";					if( i%MAX_FILES==0 || i==filesToPack.count() ){      			addProc.start(KProcess::NotifyOnExit,KProcess::AllOutput);      			while( addProc.isRunning() ) qApp->processEvents(); // busy wait - need to find something better...        		addProc.clearArguments();		    		addProc << addCmd << "\""+arcFile+"\"";					}    		}			}			krApp->stopWait();		} 	}  chdir(save.local8Bit());}vfileDict* arc_vfs::findDir(QString 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(QString name){for(arc_dir* temp = dirList.first();temp != 0 ; temp = dirList.next()){    if(temp->name == name) return temp;  }  return 0;}QString arc_vfs::changeDir(QString name){  if(name.left(2) == "./") {    prefix = "./";    name.remove(0,2);  }  if(!name.contains('/')){    vfs_filesP = findDir("");    return name;  }  // seperate the path from the name  QString 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   QString Pname = path.mid(path.findRev('/')+1);   if(Pname.isEmpty()) return name;   QString tempName = arcFile;   QFileInfo qfi(tempName.replace(QRegExp("\\"),""));   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 spacevoid arc_vfs::vfs_calcSpace(QString name ,KIO::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  QString 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);    QString 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 QString& name, QStringList *urls,KIO::filesize_t *totalSize,unsigned long *totalFiles ){  vfile* vf = vfs_search(name);	if ( vf == 0 ) return;  // get the path inside the archive  QString 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+"/");    QString 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(QString line, QFile* temp){  QString name;  KIO::filesize_t size = 0;  QString perm;  QFileInfo qfi(arcFile);  time_t mtime = qfi.lastModified().toTime_t();  bool link = false;  uid_t owner = getuid();  gid_t group = getgid();  QString 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::mode2QString(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::mode2QString(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);    QString 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);    QString 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);		QString tempName = arcFile;    QFileInfo qfi(tempName.replace(QRegExp("\\"),""));		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::mode2QString(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;  QString 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"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?