/***************************************************************************
virt_vfs . cpp - description
- - - - - - - - - - - - - - - - - - -
begin : Fri Dec 5 2003
copyright : ( C ) 2003 by Shie Erlich & Rafi Yanai
email :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* 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 <unistd.h>
# include <time.h>
# include <tdefileitem.h>
# include <tdeglobalsettings.h>
# include <kurl.h>
# include <tdemessagebox.h>
# include <tdelocale.h>
# include <kdirsize.h>
# include <kstandarddirs.h>
# include "krpermhandler.h"
# include "../krusader.h"
# include "../defaults.h"
# include "virt_vfs.h"
# define VIRT_VFS_DB "virt_vfs.db"
TQDict < KURL : : List > virt_vfs : : virtVfsDict ;
TDEConfig * virt_vfs : : virt_vfs_db = 0 ;
virt_vfs : : virt_vfs ( TQObject * panel , bool quiet ) : vfs ( panel , quiet ) {
// set the writable attribute
isWritable = true ;
virtVfsDict . setAutoDelete ( true ) ;
if ( virtVfsDict . isEmpty ( ) ) {
restore ( ) ;
}
vfs_type = VIRT ;
}
virt_vfs : : ~ virt_vfs ( ) { }
bool virt_vfs : : populateVfsList ( const KURL & origin , bool /*showHidden*/ ) {
vfs_origin = origin ;
vfs_origin . adjustPath ( - 1 ) ;
path = origin . path ( - 1 ) . mid ( 1 ) ;
if ( path . isEmpty ( ) ) path = " / " ;
KURL : : List * urlList = virtVfsDict [ path ] ;
if ( ! urlList ) {
urlList = new KURL : : List ( ) ;
virtVfsDict . insert ( path , urlList ) ;
virtVfsDict [ " / " ] - > append ( KURL : : fromPathOrURL ( " virt:/ " + path ) ) ;
}
if ( urlList - > isEmpty ( ) ) return true ;
KURL : : List : : iterator it ;
for ( it = urlList - > begin ( ) ; it ! = urlList - > end ( ) ; /*++it*/ ) {
KURL url = * it ;
// translate url->vfile and remove urls that no longer exist from the list
vfile * vf = stat ( url ) ;
if ( ! vf ) {
it = urlList - > remove ( it ) ;
// the iterator is advanced automaticly
continue ;
}
foundVfile ( vf ) ;
+ + it ;
}
save ( ) ;
return true ;
}
void virt_vfs : : vfs_addFiles ( KURL : : List * fileUrls , TDEIO : : CopyJob : : CopyMode /*mode*/ , TQObject * /*toNotify*/ , TQString /*dir*/ , PreserveMode /*pmode*/ ) {
if ( path = = " / " ) {
if ( ! quietMode )
KMessageBox : : error ( krApp , i18n ( " You can't copy files directly to the 'virt:/' directory. \n You can create a sub directory and copy your files into it. " ) , i18n ( " Error " ) ) ;
return ;
}
KURL : : List * urlList = virtVfsDict [ path ] ;
for ( unsigned i = 0 ; i ! = fileUrls - > count ( ) ; i + + ) {
if ( ! urlList - > contains ( ( * fileUrls ) [ i ] ) )
urlList - > push_back ( ( * fileUrls ) [ i ] ) ;
}
vfs_refresh ( ) ;
}
void virt_vfs : : vfs_delFiles ( TQStringList * fileNames ) {
if ( path = = " / " ) {
for ( uint i = 0 ; i < fileNames - > count ( ) ; + + i ) {
TQString filename = ( * fileNames ) [ i ] ;
virtVfsDict [ " / " ] - > remove ( TQString ( " virt:/ " ) + filename ) ;
virtVfsDict . remove ( filename ) ;
}
vfs_refresh ( ) ;
return ;
}
KURL : : List filesUrls ;
KURL url ;
// names -> urls
for ( uint i = 0 ; i < fileNames - > count ( ) ; + + i ) {
TQString filename = ( * fileNames ) [ i ] ;
filesUrls . append ( vfs_getFile ( filename ) ) ;
}
TDEIO : : Job * job ;
// delete of move to trash ?
krConfig - > setGroup ( " General " ) ;
if ( krConfig - > readBoolEntry ( " Move To Trash " , _MoveToTrash ) ) {
# if KDE_IS_VERSION(3,4,0)
job = TDEIO : : trash ( filesUrls , true ) ;
# else
job = new TDEIO : : CopyJob ( filesUrls , TDEGlobalSettings : : trashPath ( ) , TDEIO : : CopyJob : : Move , false , true ) ;
# endif
connect ( job , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , krApp , TQ_SLOT ( changeTrashIcon ( ) ) ) ;
} else
job = new TDEIO : : DeleteJob ( filesUrls , false , true ) ;
// refresh will remove the deleted files...
connect ( job , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , this , TQ_SLOT ( vfs_refresh ( TDEIO : : Job * ) ) ) ;
}
void virt_vfs : : vfs_removeFiles ( TQStringList * fileNames ) {
if ( path = = " / " )
return ;
// removing the URLs from the collection
for ( uint i = 0 ; i < fileNames - > count ( ) ; + + i ) {
KURL : : List * urlList = virtVfsDict [ path ] ;
if ( urlList )
urlList - > remove ( vfs_getFile ( ( * fileNames ) [ i ] ) ) ;
}
vfs_refresh ( ) ;
}
KURL : : List * virt_vfs : : vfs_getFiles ( TQStringList * names ) {
KURL url ;
KURL : : List * urls = new KURL : : List ( ) ;
for ( TQStringList : : Iterator name = names - > begin ( ) ; name ! = names - > end ( ) ; + + name ) {
url = vfs_getFile ( * name ) ;
urls - > append ( url ) ;
}
return urls ;
}
KURL virt_vfs : : vfs_getFile ( const TQString & name ) {
vfile * vf = vfs_search ( name ) ;
if ( ! vf ) return KURL ( ) ; // empty
KURL url = vf - > vfile_getUrl ( ) ;
if ( vf - > vfile_isDir ( ) ) url . adjustPath ( + 1 ) ;
return url ;
}
void virt_vfs : : vfs_mkdir ( const TQString & name ) {
if ( path ! = " / " ) {
if ( ! quietMode )
KMessageBox : : error ( krApp , i18n ( " Creating new directories is allowed only in the 'virt:/' directory. " ) , i18n ( " Error " ) ) ;
return ;
}
KURL : : List * temp = new KURL : : List ( ) ;
virtVfsDict . insert ( name , temp ) ;
virtVfsDict [ " / " ] - > append ( TQString ( " virt:/ " ) + name ) ;
vfs_refresh ( ) ;
}
void virt_vfs : : vfs_rename ( const TQString & fileName , const TQString & newName ) {
KURL : : List fileUrls ;
KURL url , dest ;
vfile * vf = vfs_search ( fileName ) ;
if ( ! vf ) return ; // not found
if ( path = = " / " ) {
virtVfsDict [ " / " ] - > append ( TQString ( " virt:/ " ) + newName ) ;
virtVfsDict [ " / " ] - > remove ( TQString ( " virt:/ " ) + fileName ) ;
virtVfsDict . insert ( newName , virtVfsDict . take ( fileName ) ) ;
vfs_refresh ( ) ;
return ;
}
url = vf - > vfile_getUrl ( ) ;
fileUrls . append ( url ) ;
dest = fromPathOrURL ( newName ) ;
// add the new url to the list
// the the list is refreshed only existing files remain -
// so we don't have to worry if the job was successful
virtVfsDict [ path ] - > append ( dest ) ;
TDEIO : : Job * job = new TDEIO : : CopyJob ( fileUrls , dest , TDEIO : : CopyJob : : Move , true , false ) ;
connect ( job , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , this , TQ_SLOT ( vfs_refresh ( TDEIO : : Job * ) ) ) ;
}
void virt_vfs : : slotStatResult ( TDEIO : : Job * job ) {
if ( ! job | | job - > error ( ) ) entry = TDEIO : : UDSEntry ( ) ;
else entry = static_cast < TDEIO : : StatJob * > ( job ) - > statResult ( ) ;
busy = false ;
}
vfile * virt_vfs : : stat ( const KURL & url ) {
if ( url . protocol ( ) = = " virt " ) {
TQString path = url . path ( ) . mid ( 1 ) ;
if ( path . isEmpty ( ) ) path = " / " ;
vfile * temp = new vfile ( path , 0 , " drwxr-xr-x " , time ( 0 ) , false , getuid ( ) , getgid ( ) , " inode/directory " , " " , 0 ) ;
temp - > vfile_setUrl ( url ) ;
return temp ;
}
KFileItem * kfi ;
if ( url . isLocalFile ( ) ) {
kfi = new KFileItem ( KFileItem : : Unknown , KFileItem : : Unknown , url , true ) ;
}
else {
busy = true ;
TDEIO : : StatJob * statJob = TDEIO : : stat ( url , false ) ;
connect ( statJob , TQ_SIGNAL ( result ( TDEIO : : Job * ) ) , this , TQ_SLOT ( slotStatResult ( TDEIO : : Job * ) ) ) ;
while ( busy & & vfs_processEvents ( ) ) ;
if ( entry . isEmpty ( ) ) return 0 ; // statJob failed
kfi = new KFileItem ( entry , url , true ) ;
}
if ( ! kfi - > time ( TDEIO : : UDS_MODIFICATION_TIME ) ) {
delete kfi ;
return 0 ; // file not found
}
vfile * temp ;
// get file statistics
TQString name ;
if ( url . isLocalFile ( ) )
name = url . path ( ) ;
else
name = url . prettyURL ( ) ;
TDEIO : : filesize_t size = kfi - > size ( ) ;
time_t mtime = kfi - > time ( TDEIO : : UDS_MODIFICATION_TIME ) ;
bool symLink = kfi - > isLink ( ) ;
mode_t mode = kfi - > mode ( ) | kfi - > permissions ( ) ;
TQString perm = KRpermHandler : : mode2TQString ( mode ) ;
// set the mimetype
TQString mime = TQString ( ) ;
TQString symDest = " " ;
if ( symLink ) {
symDest = kfi - > linkDest ( ) ;
if ( kfi - > isDir ( ) ) perm [ 0 ] = ' d ' ;
}
// create a new virtual file object
if ( kfi - > user ( ) . isEmpty ( ) )
temp = new vfile ( name , size , perm , mtime , symLink , getuid ( ) , getgid ( ) , mime , symDest , mode ) ;
else {
TQString currentUser = url . user ( ) ;
if ( currentUser . contains ( " @ " ) ) /* remove the FTP proxy tags from the username */
currentUser . truncate ( currentUser . find ( ' @ ' ) ) ;
if ( currentUser . isEmpty ( ) )
currentUser = KRpermHandler : : uid2user ( getuid ( ) ) ;
temp = new vfile ( name , size , perm , mtime , symLink , kfi - > user ( ) , kfi - > group ( ) , currentUser , mime , symDest , mode ) ;
}
temp - > vfile_setUrl ( kfi - > url ( ) ) ;
delete kfi ;
return temp ;
}
TDEConfig * virt_vfs : : getVirtDB ( ) {
if ( ! virt_vfs_db ) {
virt_vfs_db = new TDEConfig ( VIRT_VFS_DB , false , " data " ) ;
}
return virt_vfs_db ;
}
bool virt_vfs : : save ( ) {
TDEConfig * db = getVirtDB ( ) ;
db - > setGroup ( " virt_db " ) ;
TQDictIterator < KURL : : List > it ( virtVfsDict ) ; // See TQDictIterator
for ( ; it . current ( ) ; + + it ) {
KURL : : List : : iterator url ;
TQStringList entry ;
for ( url = it . current ( ) - > begin ( ) ; url ! = it . current ( ) - > end ( ) ; + + url ) {
entry . append ( ( * url ) . prettyURL ( ) ) ;
}
db - > writeEntry ( it . currentKey ( ) , entry ) ;
}
db - > sync ( ) ;
return true ;
}
bool virt_vfs : : restore ( ) {
TDEConfig * db = getVirtDB ( ) ;
db - > setGroup ( " virt_db " ) ;
TQMap < TQString , TQString > map = db - > entryMap ( " virt_db " ) ;
TQMap < TQString , TQString > : : Iterator it ;
KURL : : List * urlList ;
for ( it = map . begin ( ) ; it ! = map . end ( ) ; + + it ) {
urlList = new KURL : : List ( db - > readListEntry ( it . key ( ) ) ) ;
virtVfsDict . insert ( it . key ( ) , urlList ) ;
}
if ( ! virtVfsDict [ " / " ] ) {
urlList = new KURL : : List ( ) ;
virtVfsDict . insert ( " / " , urlList ) ;
}
return true ;
}
void virt_vfs : : vfs_calcSpace ( TQString name , TDEIO : : filesize_t * totalSize , unsigned long * totalFiles , unsigned long * totalDirs , bool * stop ) {
if ( stop & & * stop ) return ;
if ( path = = " / " ) {
KURL : : List * urlList = virtVfsDict [ name ] ;
if ( urlList )
for ( unsigned i = 0 ; ( i ! = urlList - > size ( ) ) & & ! ( * stop ) ; i + + )
calculateURLSize ( ( * urlList ) [ i ] , totalSize , totalFiles , totalDirs , stop ) ;
return ;
}
return vfs : : vfs_calcSpace ( name , totalSize , totalFiles , totalDirs , stop ) ;
}
# include "virt_vfs.moc"