/***************************************************************************
smb4kmounter . cpp - The core class that mounts the shares .
- - - - - - - - - - - - - - - - - - -
begin : Die Jun 10 2003
copyright : ( C ) 2003 - 2007 by Alexander Reinholdt
email : dustpuppy @ users . berlios . de
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* 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 . *
* *
* This program is distributed in the hope that it will be useful , but *
* WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU *
* General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , *
* MA 02110 - 1301 USA *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// TQt includes
# include <tqapplication.h>
# include <tqdir.h>
# include <tqtextstream.h>
# include <tqfile.h>
# include <tqtextstream.h>
// KDE includes
# include <tdeapplication.h>
# include <tdelocale.h>
# include <tdemessagebox.h>
# include <kdebug.h>
// system includes
# if !defined(__FreeBSD__) && !defined(__sun)
# include <sys/statfs.h>
# elif defined(__sun)
# include <sys/statvfs.h>
# elif defined(__FreeBSD__)
# include <sys/param.h>
# include <sys/mount.h>
# endif
# include <sys/types.h>
# include <pwd.h>
# include <unistd.h>
# include <errno.h>
# include <dirent.h>
# ifdef __FreeBSD__
# include <sys/param.h>
# include <sys/ucred.h>
# include <sys/mount.h>
# include <tqfileinfo.h>
# endif
// Application specific includes
# include "smb4kmounter.h"
# include "smb4kmounter_p.h"
# include "smb4kauthinfo.h"
# include "smb4ksambaoptionsinfo.h"
# include "smb4kerror.h"
# include "smb4tdeglobal.h"
# include "smb4ksambaoptionshandler.h"
# include "smb4kpasswordhandler.h"
# include "smb4kshare.h"
# include "smb4ksettings.h"
using namespace Smb4TDEGlobal ;
Smb4KMounter : : Smb4KMounter ( TQObject * parent , const char * name ) : TQObject ( parent , name )
{
m_priv = new Smb4KMounterPrivate ;
m_proc = new TDEProcess ( this , " MounterProcess " ) ;
m_proc - > setUseShell ( true ) ;
m_working = false ;
m_queue . setAutoDelete ( true ) ;
connect ( m_proc , TQT_SIGNAL ( processExited ( TDEProcess * ) ) ,
this , TQT_SLOT ( slotProcessExited ( TDEProcess * ) ) ) ;
connect ( m_proc , TQT_SIGNAL ( receivedStdout ( TDEProcess * , char * , int ) ) ,
this , TQT_SLOT ( slotReceivedStdout ( TDEProcess * , char * , int ) ) ) ;
connect ( m_proc , TQT_SIGNAL ( receivedStderr ( TDEProcess * , char * , int ) ) ,
this , TQT_SLOT ( slotReceivedStderr ( TDEProcess * , char * , int ) ) ) ;
connect ( kapp , TQT_SIGNAL ( shutDown ( ) ) ,
this , TQT_SLOT ( slotShutdown ( ) ) ) ;
}
Smb4KMounter : : ~ Smb4KMounter ( )
{
abort ( ) ;
for ( TQValueList < Smb4KShare * > : : Iterator it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
delete * it ;
}
m_mounted_shares . clear ( ) ;
delete m_priv ;
}
void Smb4KMounter : : init ( )
{
m_queue . enqueue ( new TQString ( TQString ( " %1: " ) . arg ( Import ) ) ) ;
m_queue . enqueue ( new TQString ( TQString ( " %1: " ) . arg ( Remount ) ) ) ;
startTimer ( TIMER_INTERVAL ) ;
}
/***************************************************************************
Aborts any action of the mounter .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : abort ( )
{
m_queue . clear ( ) ;
if ( m_proc - > isRunning ( ) )
{
if ( Smb4KSettings : : alwaysUseSuperUser ( ) )
{
TQString suid_program ;
switch ( Smb4KSettings : : superUserProgram ( ) )
{
case Smb4KSettings : : EnumSuperUserProgram : : Sudo :
{
suid_program = Smb4KSettings : : sudo ( ) ;
break ;
}
case Smb4KSettings : : EnumSuperUserProgram : : Super :
{
suid_program = Smb4KSettings : : super ( ) ;
break ;
}
default :
{
// FIXME: Throw an error?
return ;
}
}
TDEProcess proc ;
proc . setUseShell ( true ) ;
proc < < TQString ( " %1 smb4k_kill %2 " ) . arg ( suid_program ) . arg ( m_proc - > pid ( ) ) ;
proc . start ( TDEProcess : : DontCare , TDEProcess : : NoCommunication ) ;
}
else
{
m_proc - > kill ( ) ;
}
}
}
/***************************************************************************
Mounts recently used shares .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : remount ( )
{
if ( Smb4KSettings : : remountShares ( ) )
{
const TQValueList < Smb4KSambaOptionsInfo * > * list = & ( optionsHandler ( ) - > customOptionsList ( ) ) ;
for ( TQValueList < Smb4KSambaOptionsInfo * > : : ConstIterator it = list - > begin ( ) ;
it ! = list - > end ( ) ; + + it )
{
if ( ( * it ) - > remount ( ) )
{
TQValueList < Smb4KShare > list = findShareByName ( ( * it ) - > itemName ( ) ) ;
bool mount = true ;
if ( ! list . isEmpty ( ) )
{
for ( TQValueList < Smb4KShare > : : ConstIterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
{
if ( ! ( * it ) . isForeign ( ) )
{
mount = false ;
break ;
}
else
{
continue ;
}
}
}
if ( mount )
{
# ifndef __FreeBSD__
mountShare ( TQString ( ) , ( * it ) - > itemName ( ) . section ( " / " , 2 , 2 ) , TQString ( ) , ( * it ) - > itemName ( ) . section ( " / " , 3 , 3 ) ) ;
# else
mountShare ( TQString ( ) , ( * it ) - > itemName ( ) . section ( " / " , 2 , 2 ) . section ( " @ " , 1 , 1 ) , TQString ( ) , ( * it ) - > itemName ( ) . section ( " / " , 3 , 3 ) ) ;
# endif
}
// If the share is to be remounted the next time,
// slotShutdown() will tell the options handler.
( * it ) - > setRemount ( false ) ;
continue ;
}
else
{
continue ;
}
}
m_working = false ;
emit state ( MOUNTER_STOP ) ;
}
else
{
m_working = false ;
emit state ( MOUNTER_STOP ) ;
}
}
/***************************************************************************
Imports all shares , that are mounted externally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : import ( )
{
TQValueList < Smb4KShare * > shares ;
# ifndef __FreeBSD__
if ( m_proc_mounts . name ( ) . isEmpty ( ) )
{
m_proc_mounts . setName ( " /proc/mounts " ) ;
}
if ( ! TQFile : : exists ( m_proc_mounts . name ( ) ) )
{
if ( ! m_proc_error )
{
m_proc_error = true ;
Smb4KError : : error ( ERROR_FILE_NOT_FOUND , m_proc_mounts . name ( ) ) ;
}
else
{
// No need to do anything here
}
}
else
{
TQStringList contents , list ;
// Read /proc/mounts:
if ( m_proc_mounts . open ( IO_ReadOnly ) )
{
TQTextStream ts ( & m_proc_mounts ) ;
ts . setEncoding ( TQTextStream : : Locale ) ;
contents = TQStringList : : split ( " \n " , ts . read ( ) , false ) ;
m_proc_mounts . close ( ) ;
}
else
{
Smb4KError : : error ( ERROR_OPENING_FILE , m_proc_mounts . name ( ) ) ;
return ;
}
// Process the SMBFS and CIFS entries:
list + = contents . grep ( " smbfs " , true ) ;
list + = contents . grep ( " cifs " , true ) ;
if ( ! list . isEmpty ( ) )
{
for ( TQStringList : : Iterator it = list . begin ( ) ; it ! = list . end ( ) ; it + + )
{
Smb4KShare * new_share = NULL ;
if ( ( * it ) . contains ( " smbfs " , false ) ! = 0 )
{
TQString share_and_path = ( * it ) . section ( " smbfs " , 0 , 0 ) . stripWhiteSpace ( ) ;
TQString name = share_and_path . section ( " " , 0 , 0 ) . stripWhiteSpace ( ) . replace ( " \\ 040 " , " \040 " ) ;
TQString path = share_and_path . section ( " " , 1 , 1 ) . stripWhiteSpace ( ) ;
if ( path . contains ( " \\ 040 " ) ! = 0 | | path . contains ( " \040 " ) ! = 0 )
{
name . replace ( " _ " , " \040 " ) ;
path . replace ( " \\ 040 " , " \040 " ) ;
}
int uid = ( * it ) . section ( " uid= " , 1 , 1 ) . section ( " , " , 0 , 0 ) . stripWhiteSpace ( ) . toInt ( ) ;
int gid = ( * it ) . section ( " gid= " , 1 , 1 ) . section ( " , " , 0 , 0 ) . stripWhiteSpace ( ) . toInt ( ) ;
new_share = new Smb4KShare ( name , path , " smbfs " , uid , gid ) ;
}
else if ( ( * it ) . contains ( " cifs " , false ) ! = 0 )
{
TQString share_and_path = ( * it ) . section ( " cifs " , 0 , 0 ) . stripWhiteSpace ( ) ;
TQString name = share_and_path . section ( " " , 0 , 0 ) . stripWhiteSpace ( ) . replace ( " \\ 040 " , " \040 " ) ;
TQString path = share_and_path . section ( " " , 1 , 1 ) . stripWhiteSpace ( ) ;
if ( path . contains ( " \\ 040 " ) ! = 0 | | path . contains ( " \040 " ) ! = 0 )
{
name . replace ( " _ " , " \040 " ) ;
path . replace ( " \\ 040 " , " \040 " ) ;
}
TQString login = ( * it ) . section ( " username= " , 1 , 1 ) . section ( " , " , 0 , 0 ) . stripWhiteSpace ( ) ;
new_share = new Smb4KShare ( name , path , " cifs " , login ) ;
}
else
{
continue ;
}
if ( new_share )
{
// If the a representative of the new share is already in the list of
// mounted shares, replace the new with the old one.
Smb4KShare * existing_share = findShareByPath ( new_share - > path ( ) ) ;
if ( existing_share )
{
delete new_share ;
new_share = new Smb4KShare ( * existing_share ) ;
}
// Check if the share is broken and/or foreign.
if ( ( existing_share & & ! existing_share - > isBroken ( ) ) | | ! existing_share )
{
checkAccessibility ( new_share ) ;
}
else
{
// Since new_share is a copy of existing_share, we do not need to do
// anything here.
}
if ( ! existing_share & & TQString : : compare ( new_share - > filesystem ( ) , " cifs " ) = = 0 )
{
bool foreign = true ;
if ( ( ! new_share - > isBroken ( ) & &
( tqstrncmp ( new_share - > canonicalPath ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) . length ( ) ) = = 0 | |
tqstrncmp ( new_share - > canonicalPath ( ) ,
TQDir : : home ( ) . canonicalPath ( ) ,
TQDir : : home ( ) . canonicalPath ( ) . length ( ) ) = = 0 ) ) | |
( new_share - > isBroken ( ) & &
( tqstrncmp ( new_share - > path ( ) ,
TQDir : : homeDirPath ( ) ,
TQDir : : homeDirPath ( ) . length ( ) ) = = 0 | |
tqstrncmp ( new_share - > path ( ) ,
Smb4KSettings : : mountPrefix ( ) ,
Smb4KSettings : : mountPrefix ( ) . length ( ) ) = = 0 ) ) )
{
foreign = false ;
}
new_share - > setForeign ( foreign ) ;
}
shares . append ( new_share ) ;
}
}
}
}
# else
struct statfs * buf ;
int count = getmntinfo ( & buf , 0 ) ;
if ( count = = 0 )
{
int err_code = errno ;
Smb4KError : : error ( ERROR_IMPORTING_SHARES , TQString ( ) , strerror ( err_code ) ) ;
m_working = false ;
return ;
}
for ( int i = 0 ; i < count ; + + i )
{
if ( ! strcmp ( buf [ i ] . f_fstypename , " smbfs " ) )
{
TQString share_name ( buf [ i ] . f_mntfromname ) ;
TQString path ( buf [ i ] . f_mntonname ) ;
TQString fs ( buf [ i ] . f_fstypename ) ;
TQFileInfo info ( TQString ( buf [ i ] . f_mntonname ) + " /. " ) ;
int uid = ( int ) info . ownerId ( ) ;
int gid = ( int ) info . groupId ( ) ;
Smb4KShare * existing_share = findShareByPath ( path ) ;
Smb4KShare * new_share = NULL ;
if ( existing_share )
{
new_share = new Smb4KShare ( * existing_share ) ;
}
else
{
new_share = new Smb4KShare ( share_name , path , fs , uid , gid ) ;
}
// Test if share is broken
if ( ( existing_share & & ! existing_share - > isBroken ( ) ) | | ! existing_share )
{
checkAccessibility ( new_share ) ;
}
else
{
// Since new_share is a copy of existing_share, we do not need to do
// anything here.
}
shares . append ( new_share ) ;
}
}
// Apparently, under FreeBSD we do not need to delete
// the pointer (see manual page).
# endif
// Delete all entries of m_mounted_shares.
for ( TQValueList < Smb4KShare * > : : Iterator it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
delete * it ;
}
m_mounted_shares . clear ( ) ;
m_mounted_shares = shares ;
emit updated ( ) ;
m_working = false ;
}
/***************************************************************************
Mounts a share . ( Public part )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : mountShare ( const TQString & workgroup , const TQString & host , const TQString & ip , const TQString & share )
{
TQString share_name = TQString ( ) ;
if ( TQString : : compare ( share , " homes " ) = = 0 )
{
share_name = specifyUser ( host , kapp - > mainWidget ( ) ? kapp - > mainWidget ( ) : 0 , " SpecifyUser " ) ;
}
else
{
share_name = share ;
}
if ( ! share_name . stripWhiteSpace ( ) . isEmpty ( ) )
{
// Before doing anything else let's check that the
// share has not been mounted by the user already:
TQValueList < Smb4KShare > list = findShareByName ( TQString ( " //%1/%2 " ) . arg ( host , share_name ) ) ;
for ( TQValueList < Smb4KShare > : : ConstIterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
{
if ( ! ( * it ) . isForeign ( ) )
{
emit mountedShare ( ( * it ) . canonicalPath ( ) ) ;
return ;
}
}
m_queue . enqueue ( new TQString ( TQString ( " %1:%2:%3:%4:%5 " ) . arg ( Mount )
. arg ( workgroup , host )
. arg ( ip , share_name ) ) ) ;
}
}
/***************************************************************************
Mounts a share . ( Private part )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : mount ( const TQString & workgroup , const TQString & host , const TQString & ip , const TQString & share )
{
m_priv - > setWorkgroup ( workgroup ) ;
m_priv - > setHost ( host ) ;
m_priv - > setShare ( share ) ;
m_priv - > setIP ( ip ) ;
// Create the mount point:
TQDir * dir = new TQDir ( Smb4KSettings : : mountPrefix ( ) ) ;
if ( ! dir - > exists ( ) )
{
if ( ! dir - > mkdir ( dir - > canonicalPath ( ) ) )
{
Smb4KError : : error ( ERROR_MKDIR_FAILED , dir - > path ( ) ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
dir - > setPath ( dir - > path ( ) + " / " +
( Smb4KSettings : : forceLowerCaseSubdirs ( ) ?
m_priv - > host ( ) . lower ( ) :
m_priv - > host ( ) ) ) ;
if ( ! dir - > exists ( ) )
{
if ( ! dir - > mkdir ( dir - > canonicalPath ( ) ) )
{
Smb4KError : : error ( ERROR_MKDIR_FAILED , dir - > path ( ) ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
dir - > setPath ( dir - > path ( ) + " / " +
( Smb4KSettings : : forceLowerCaseSubdirs ( ) ?
m_priv - > share ( ) . lower ( ) :
m_priv - > share ( ) ) ) ;
if ( ! dir - > exists ( ) )
{
if ( ! dir - > mkdir ( dir - > canonicalPath ( ) ) )
{
Smb4KError : : error ( ERROR_MKDIR_FAILED , dir - > path ( ) ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
m_priv - > setPath ( TQDir : : cleanDirPath ( dir - > path ( ) ) ) ;
delete dir ;
// Now we are prepared to mount the share:
TQString command , suid_program ;
switch ( Smb4KSettings : : superUserProgram ( ) )
{
case Smb4KSettings : : EnumSuperUserProgram : : Sudo :
{
suid_program = " sudo " ;
break ;
}
case Smb4KSettings : : EnumSuperUserProgram : : Super :
{
suid_program = " super " ;
break ;
}
default :
{
return ;
}
}
Smb4KAuthInfo authInfo ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > share ( ) ) ;
( void ) passwordHandler ( ) - > readAuth ( & authInfo ) ;
# ifndef __FreeBSD__
// Let's see if the options handler knows the share:
Smb4KSambaOptionsInfo * info = optionsHandler ( ) - > findItem ( TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) ) , true ) ;
// Determine the file system we have to use:
int filesystem ;
if ( info )
{
filesystem = TQString : : compare ( info - > filesystem ( ) . lower ( ) , " cifs " ) = = 0 ?
Smb4KSettings : : EnumFilesystem : : CIFS :
Smb4KSettings : : EnumFilesystem : : SMBFS ;
}
else
{
filesystem = Smb4KSettings : : filesystem ( ) ;
}
// Compile the mount command:
switch ( filesystem )
{
case Smb4KSettings : : EnumFilesystem : : CIFS :
{
command . append ( Smb4KSettings : : alwaysUseSuperUser ( ) ? // FIXME: Check if suid program is installed
TQString ( " %1 smb4k_mount -s -t cifs " ) . arg ( suid_program ) :
" smb4k_mount -n -t cifs " ) ;
command . append ( " -o " ) ;
command . append ( optionsHandler ( ) - > mountOptions ( TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) ) ) ) ;
command . append ( ! m_priv - > workgroup ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " domain='%1', " ) . arg ( m_priv - > workgroup ( ) ) :
" " ) ;
command . append ( ! m_priv - > ip ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " ip=%1, " ) . arg ( m_priv - > ip ( ) ) :
" " ) ;
command . append ( ! authInfo . user ( ) . isEmpty ( ) ?
TQString ( " user=%1 " ) . arg ( authInfo . user ( ) . data ( ) ) :
" guest " ) ;
command . append ( " -- " ) ;
command . append ( TQString ( " //'%1'/'%2' '%3' " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) , m_priv - > path ( ) ) ) ;
m_priv - > setCIFSLogin ( ! authInfo . user ( ) . isEmpty ( ) ?
authInfo . user ( ) :
" guest " ) ;
m_priv - > setFileSystem ( " cifs " ) ;
break ;
}
case Smb4KSettings : : EnumFilesystem : : SMBFS :
{
command . append ( Smb4KSettings : : alwaysUseSuperUser ( ) ? // FIXME: Check if suid program is installed
TQString ( " %1 smb4k_mount -s -t smbfs " ) . arg ( suid_program ) :
" smb4k_mount -n -t smbfs " ) ;
command . append ( " -o " ) ;
command . append ( optionsHandler ( ) - > mountOptions ( TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) ) ) ) ;
command . append ( ! m_priv - > workgroup ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " workgroup='%1', " ) . arg ( m_priv - > workgroup ( ) ) :
" " ) ;
command . append ( ! m_priv - > ip ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " ip=%1, " ) . arg ( m_priv - > ip ( ) ) :
" " ) ;
command . append ( ! authInfo . user ( ) . isEmpty ( ) ?
TQString ( " username=%1 " ) . arg ( authInfo . user ( ) . data ( ) ) :
" guest " ) ;
command . append ( " -- " ) ;
command . append ( TQString ( " //'%1'/'%2' '%3' " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) , m_priv - > path ( ) ) ) ;
m_priv - > setFileSystem ( " smbfs " ) ;
break ;
}
default :
{
return ;
}
}
m_proc - > setEnvironment ( " PASSWD " , ! authInfo . password ( ) . isEmpty ( ) ? authInfo . password ( ) : " " ) ;
# else
Smb4KSambaOptionsInfo * info = optionsHandler ( ) - > findItem ( " // " + m_priv - > host ( ) + " / " + m_priv - > share ( ) ) ;
int port = info & & info - > port ( ) ! = - 1 ?
info - > port ( ) :
Smb4KSettings : : remotePort ( ) ;
command . append ( Smb4KSettings : : alwaysUseSuperUser ( ) ? // FIXME: Check if suid program is installed
TQString ( " %1 smb4k_mount " ) . arg ( suid_program ) :
" smb4k_mount " ) ;
command . append ( optionsHandler ( ) - > mountOptions ( TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) , m_priv - > share ( ) ) ) ) ;
command . append ( ! m_priv - > workgroup ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " -W '%1' " ) . arg ( m_priv - > workgroup ( ) ) :
" " ) ;
command . append ( ! m_priv - > ip ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
TQString ( " -I %1 " ) . arg ( m_priv - > ip ( ) ) :
" " ) ;
command . append ( " -N " ) ;
command . append ( " -- " ) ;
command . append ( TQString ( " //%1@'%2':%3/'%4' '%5' " ) . arg ( ! authInfo . user ( ) . isEmpty ( ) ? authInfo . user ( ) : " guest " )
. arg ( m_priv - > host ( ) )
. arg ( port )
. arg ( m_priv - > share ( ) , m_priv - > path ( ) ) ) ;
# endif
// Start the mount process:
* m_proc < < command ;
startProcess ( Mount ) ;
}
/****************************************************************************
Unmount a share . ( Public part )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : unmountShare ( Smb4KShare * share , bool force , bool noMessage )
{
// Do *not* change share->canonicalPath(). It is necessary for the
// checks below to work.
m_queue . enqueue ( new TQString ( TQString ( " %1:%2:%3:%4 " ) . arg ( Unmount )
. arg ( share - > canonicalPath ( ) . data ( ) )
. arg ( force , noMessage ) ) ) ;
}
/***************************************************************************
Unmount a share . ( Private part )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : unmount ( const TQString & mountpoint , bool force , bool noMessage )
{
// First let's see if all requirements are fullfilled:
if ( force )
{
// Check that the user enabled the "Force Unmounting" ability:
if ( ! Smb4KSettings : : useForceUnmount ( ) )
{
Smb4KError : : error ( ERROR_FEATURE_NOT_ENABLED ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
// Compose the unmount command:
if ( ! mountpoint . stripWhiteSpace ( ) . isEmpty ( ) )
{
bool execute = false ;
TQString path = mountpoint ;
m_priv - > setPath ( path . replace ( ' \044 ' , " \044 " ) ) ;
TQString suid_program , command ;
if ( Smb4KSettings : : useForceUnmount ( ) | | Smb4KSettings : : alwaysUseSuperUser ( ) )
{
switch ( Smb4KSettings : : superUserProgram ( ) )
{
case Smb4KSettings : : EnumSuperUserProgram : : Sudo :
{
suid_program = Smb4KSettings : : sudo ( ) ;
break ;
}
case Smb4KSettings : : EnumSuperUserProgram : : Super :
{
suid_program = Smb4KSettings : : super ( ) ;
break ;
}
default :
{
// FIXME: Throw an error?
return ;
}
}
}
Smb4KShare * share = findShareByPath ( mountpoint ) ;
if ( share )
{
if ( ! share - > isForeign ( ) )
{
if ( force )
{
if ( KMessageBox : : questionYesNo ( 0 , i18n ( " Do you really want to force the unmounting of this share? " ) , TQString ( ) , KStdGuiItem : : yes ( ) , KStdGuiItem : : no ( ) , " Dont Ask Forced " , KMessageBox : : Notify ) = = KMessageBox : : Yes )
{
# ifdef __linux__
command . append ( TQString ( " %1 smb4k_umount -s -l " ) . arg ( suid_program ) ) ;
# else
# ifdef __FreeBSD__
command . append ( TQString ( " %1 smb4k_umount " ) . arg ( suid_program ) ) ;
# else
command . append ( TQString ( " %1 smb4k_umount -s " ) . arg ( suid_program ) ) ;
# endif
# endif
execute = true ;
}
else
{
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
else
{
if ( ! Smb4KSettings : : alwaysUseSuperUser ( ) )
{
# ifndef __FreeBSD__
command . append ( " smb4k_umount -n " ) ;
# else
command . append ( " smb4k_umount " ) ;
# endif
}
else
{
# ifndef __FreeBSD__
command . append ( TQString ( " %1 smb4k_umount -s " ) . arg ( suid_program ) ) ;
# else
command . append ( TQString ( " %1 smb4k_umount " ) . arg ( suid_program ) ) ;
# endif
}
}
}
else
{
if ( Smb4KSettings : : unmountForeignShares ( ) )
{
if ( force )
{
if ( KMessageBox : : questionYesNo ( 0 , i18n ( " Do you really want to force the unmounting of this share? " ) , TQString ( ) , KStdGuiItem : : yes ( ) , KStdGuiItem : : no ( ) , " Dont Ask Forced " , KMessageBox : : Notify ) = = KMessageBox : : Yes )
{
# ifdef __linux__
command . append ( TQString ( " %1 smb4k_umount -s -l " ) . arg ( suid_program ) ) ;
# else
# ifdef __FreeBSD__
command . append ( TQString ( " %1 smb4k_umount " ) . arg ( suid_program ) ) ;
# else
command . append ( TQString ( " %1 smb4k_umount -s " ) . arg ( suid_program ) ) ;
# endif
# endif
execute = true ;
}
else
{
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
else
{
if ( ! Smb4KSettings : : alwaysUseSuperUser ( ) )
{
# ifndef __FreeBSD__
command . append ( " smb4k_umount -n " ) ;
# else
command . append ( " smb4k_umount " ) ;
# endif
}
else
{
# ifndef __FreeBSD__
command . append ( TQString ( " %1 smb4k_umount -s " ) . arg ( suid_program ) ) ;
# else
command . append ( TQString ( " %1 smb4k_umount " ) . arg ( suid_program ) ) ;
# endif
}
}
}
else
{
if ( ! noMessage )
{
Smb4KError : : error ( ERROR_UNMOUNTING_NOT_ALLOWED ) ;
}
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
# ifndef __FreeBSD__
command . append ( TQString ( " -t %1 " ) . arg ( share - > filesystem ( ) ) ) ;
# endif
command . append ( TQString ( " '%1' " ) . arg ( m_priv - > path ( ) ) ) ;
if ( force & & ! execute )
{
return ;
}
emit aboutToUnmount ( mountpoint ) ;
* m_proc < < command ;
startProcess ( Unmount ) ;
}
else
{
// FIXME: Throw an error?
return ;
}
}
else
{
Smb4KError : : error ( ERROR_MOUNTPOINT_EMPTY ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
return ;
}
}
/***************************************************************************
Unmounts all shares at once . ( Public part )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : unmountAllShares ( )
{
m_queue . enqueue ( new TQString ( TQString ( " %1 " ) . arg ( UnmountAll ) ) ) ;
}
/***************************************************************************
Unmounts all shares at once .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : unmountAll ( )
{
for ( TQValueListIterator < Smb4KShare * > it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
unmountShare ( * it , false , true ) ;
}
m_working = false ;
}
/***************************************************************************
Starts any process .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : startProcess ( int state )
{
m_buffer = TQString ( ) ;
m_state = state ;
if ( m_state ! = Import )
{
TQApplication : : setOverrideCursor ( waitCursor ) ;
}
m_proc - > start ( TDEProcess : : NotifyOnExit , TDEProcess : : AllOutput ) ;
}
/***************************************************************************
Ends any process . This functions tells the mounter what to do
afterwards .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : endProcess ( )
{
switch ( m_state )
{
case Mount :
processMount ( ) ;
break ;
case Unmount :
processUnmount ( ) ;
break ;
default :
break ;
}
m_state = Idle ;
m_priv - > clearData ( ) ;
TQApplication : : restoreOverrideCursor ( ) ;
m_proc - > clearArguments ( ) ;
m_working = false ;
emit state ( MOUNTER_STOP ) ;
}
/***************************************************************************
Process mounts .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : processMount ( )
{
Smb4KShare * share = NULL ;
# ifndef __FreeBSD__
if ( m_proc - > normalExit ( ) )
{
if ( m_buffer . contains ( " smb4k_mount: " , true ) = = 0 & &
m_buffer . contains ( " failed " , true ) = = 0 & &
m_buffer . contains ( " ERR " , true ) = = 0 & &
m_buffer . contains ( " /bin/sh: " ) = = 0 & &
m_buffer . contains ( " mount: " , true ) = = 0 & &
m_buffer . contains ( " smbmnt " ) = = 0 & &
m_buffer . contains ( m_priv - > path ( ) ) = = 0 & &
m_buffer . contains ( " mount error " ) = = 0 & &
m_buffer . contains ( " bad user name " ) = = 0 & &
m_buffer . contains ( " bad group name " ) = = 0 )
{
TQString name = TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) ) . arg ( m_priv - > share ( ) ) ;
// Check file system
# if !defined(__sun)
struct statfs filesystem ;
# else
struct statvfs filesystem ;
# endif
# if !defined(__sun) && !defined(__irix__)
if ( statfs ( m_priv - > path ( ) , & filesystem ) = = - 1 )
# elif defined(__irix__)
if ( statfs ( m_priv - > path ( ) , & filesystem , sizeof ( filesystem ) , 0 ) = = - 1 )
# else
if ( statvfs ( m_priv - > path ( ) , & filesystem ) = = - 1 )
# endif
{
// The query failed. Go with the file system already defined in m_priv.
if ( TQString : : compare ( m_priv - > filesystem ( ) , " smbfs " ) = = 0 )
{
share = new Smb4KShare ( name , m_priv - > path ( ) , m_priv - > filesystem ( ) , ( int ) getuid ( ) , ( int ) getgid ( ) ) ;
m_mounted_shares . append ( share ) ;
}
else if ( TQString : : compare ( m_priv - > filesystem ( ) , " cifs " ) = = 0 )
{
// The user name will be send if no login was specified.
TQString cifs_login = ! m_priv - > cifsLogin ( ) . isEmpty ( ) ?
m_priv - > cifsLogin ( ) :
getpwuid ( getuid ( ) ) - > pw_name ;
share = new Smb4KShare ( name , m_priv - > path ( ) , m_priv - > filesystem ( ) , cifs_login , false ) ;
m_mounted_shares . append ( share ) ;
}
}
else
{
# if !defined(__FreeBSD__) && !defined(__sun) && !defined(__irix__)
if ( ( uint ) filesystem . f_type = = 0xFF534D42 /* CIFS */ )
{
// The user name will be send if no login was specified.
TQString cifs_login = ! m_priv - > cifsLogin ( ) . isEmpty ( ) ?
m_priv - > cifsLogin ( ) :
getpwuid ( getuid ( ) ) - > pw_name ;
share = new Smb4KShare ( name , m_priv - > path ( ) , " cifs " , cifs_login , false ) ;
m_mounted_shares . append ( share ) ;
}
else if ( ( uint ) filesystem . f_type = = 0x517B /* SMBFS */ )
{
share = new Smb4KShare ( name , m_priv - > path ( ) , " smbfs " , ( int ) getuid ( ) , ( int ) getgid ( ) ) ;
m_mounted_shares . append ( share ) ;
}
# elif defined(__sun)
if ( ( uint ) filesystem . f_basetype = = 0xFF534D42 /* CIFS */ )
{
// The user name will be send if no login was specified.
TQString cifs_login = ! m_priv - > cifsLogin ( ) . isEmpty ( ) ?
m_priv - > cifsLogin ( ) :
getpwuid ( getuid ( ) ) - > pw_name ;
share = new Smb4KShare ( name , m_priv - > path ( ) , " cifs " , cifs_login , false ) ;
m_mounted_shares . append ( share ) ;
}
else if ( ( uint ) filesystem . f_basetype = = 0x517B /* SMBFS */ )
{
share = new Smb4KShare ( name , m_priv - > path ( ) , " smbfs " , ( int ) getuid ( ) , ( int ) getgid ( ) ) ;
m_mounted_shares . append ( share ) ;
}
# elif defined(__irix__)
if ( ( uint ) filesystem . f_fstyp = = 0xFF534D42 /* CIFS */ )
{
// The user name will be send if no login was specified.
TQString cifs_login = ! m_priv - > cifsLogin ( ) . isEmpty ( ) ?
m_priv - > cifsLogin ( ) :
getpwuid ( getuid ( ) ) - > pw_name ;
share = new Smb4KShare ( name , m_priv - > path ( ) , " cifs " , cifs_login , false ) ;
m_mounted_shares . append ( share ) ;
}
else if ( ( uint ) filesystem . f_basetype = = 0x517B & & ! strncmp ( fs , " smbfs " , strlen ( fs ) + 1 ) )
{
share = new Smb4KShare ( name , m_priv - > path ( ) , " smbfs " , ( int ) getuid ( ) , ( int ) getgid ( ) ) ;
m_mounted_shares . append ( share ) ;
}
# endif
else
{
// Error... We don't create a share.
}
}
if ( share )
{
// Check that the share is accessible:
checkAccessibility ( share ) ;
emit mountedShare ( m_priv - > path ( ) ) ;
}
}
else
{
if ( m_buffer . contains ( " ERRbadpw " ) ! = 0 | |
m_buffer . contains ( " ERRnoaccess " ) ! = 0 | |
m_buffer . contains ( " mount error 13 = Permission denied " ) ! = 0 )
{
int state = Smb4KPasswordHandler : : None ;
if ( m_buffer . contains ( " ERRbadpw " ) ! = 0 )
{
state = Smb4KPasswordHandler : : BadPassword ;
}
else if ( m_buffer . contains ( " ERRnoaccess " ) ! = 0 )
{
state = Smb4KPasswordHandler : : AccessDenied ;
}
else if ( m_buffer . contains ( " mount error 13 = Permission denied " ) ! = 0 )
{
state = Smb4KPasswordHandler : : PermDenied ;
}
// If the user supplied auth information, we will retry mounting.
if ( passwordHandler ( ) - > askpass ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > share ( ) , state ) )
{
mountShare ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > ip ( ) , m_priv - > share ( ) ) ;
}
}
else if ( m_buffer . contains ( " ERRnosuchshare " ) ! = 0 & & m_priv - > share ( ) . contains ( " _ " ) ! = 0 )
{
TQString share_string = static_cast < TQString > ( m_priv - > share ( ) ) . replace ( " _ " , " " ) ;
mountShare ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > ip ( ) , share_string ) ;
}
else
{
TQString name = TQString ( " //%1/%2 " ) . arg ( m_priv - > host ( ) ) . arg ( m_priv - > share ( ) ) ;
Smb4KError : : error ( ERROR_MOUNTING_SHARE , name , m_buffer ) ;
}
}
}
# else
if ( m_proc - > normalExit ( ) )
{
if ( m_buffer . contains ( " smb4k_mount: " , true ) = = 0 & &
m_buffer . contains ( " syserr = " , true ) = = 0 & &
/* To make sure we catch all errors, also check for the following
strings . Maybe we can remove them ? ? */
m_buffer . contains ( " Authentication error " , true ) = = 0 & &
m_buffer . contains ( " Connection refused " , true ) = = 0 & &
m_buffer . contains ( " Operation not permitted " , true ) = = 0 )
{
import ( ) ; // FIXME: *cough* What is this for???
Smb4KAuthInfo authInfo ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > share ( ) ) ;
( void ) passwordHandler ( ) - > readAuth ( & authInfo ) ;
TQString name = TQString ( " //%1@%2/%3 " ) . arg ( authInfo . user ( ) . upper ( ) , m_priv - > host ( ) . upper ( ) , m_priv - > share ( ) . upper ( ) ) ;
share = new Smb4KShare ( name , m_priv - > path ( ) , m_priv - > filesystem ( ) , ( int ) getuid ( ) , ( int ) getgid ( ) ) ;
m_mounted_shares . append ( share ) ;
// Check that the share is accessible:
checkAccessibility ( share ) ;
emit mountedShare ( m_priv - > path ( ) ) ;
}
else
{
if ( m_buffer . contains ( " Authentication error " ) ! = 0 )
{
// If the user supplied auth information, we will retry mounting.
if ( passwordHandler ( ) - > askpass ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > share ( ) , Smb4KPasswordHandler : : AuthError ) )
{
mountShare ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > ip ( ) , m_priv - > share ( ) ) ;
}
}
else
{
Smb4KAuthInfo authInfo ( m_priv - > workgroup ( ) , m_priv - > host ( ) , m_priv - > share ( ) ) ;
( void ) passwordHandler ( ) - > readAuth ( & authInfo ) ;
TQString name = TQString ( " //%1@%2/%3 " ) . arg ( authInfo . user ( ) . upper ( ) , m_priv - > host ( ) . upper ( ) , m_priv - > share ( ) . upper ( ) ) ;
Smb4KError : : error ( ERROR_MOUNTING_SHARE , name , m_buffer ) ;
}
}
}
# endif
emit updated ( ) ;
}
/***************************************************************************
Process unmounts .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Smb4KMounter : : processUnmount ( )
{
// Get the share:
Smb4KShare * share = findShareByPath ( m_priv - > path ( ) ) ;
if ( m_proc - > normalExit ( ) )
{
if ( m_buffer . isEmpty ( ) )
{
if ( tqstrncmp ( share - > canonicalPath ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) . local8Bit ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) . local8Bit ( ) . length ( ) ) = = 0 )
{
TQDir dir ( share - > canonicalPath ( ) ) ;
if ( dir . rmdir ( dir . canonicalPath ( ) , true ) )
{
dir . cdUp ( ) ;
dir . rmdir ( dir . canonicalPath ( ) , true ) ;
}
}
m_mounted_shares . remove ( share ) ;
}
else
{
// If the user's computer is configured by a DHCP server, under
// rare circumstances it might occur that sudo reports an error,
// because it is not able to resolve the host. This error message
// will be removed, because it does not affect the unmounting:
if ( m_buffer . contains ( " sudo: unable to resolve host " , true ) ! = 0 )
{
size_t hostnamelen = 255 ;
char * hostname = new char [ hostnamelen ] ;
if ( gethostname ( hostname , hostnamelen ) = = - 1 )
{
int error_number = errno ;
Smb4KError : : error ( ERROR_GETTING_HOSTNAME , TQString ( ) , strerror ( error_number ) ) ;
}
else
{
TQString str = TQString ( " sudo: unable to resolve host %1 \n " ) . arg ( hostname ) ;
m_buffer . remove ( str , false /* case insensitive */ ) ;
if ( ! m_buffer . isEmpty ( ) )
{
Smb4KError : : error ( ERROR_UNMOUNTING_SHARE , share - > name ( ) , m_buffer ) ;
}
else
{
if ( tqstrncmp ( share - > canonicalPath ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) . local8Bit ( ) ,
TQDir ( Smb4KSettings : : mountPrefix ( ) ) . canonicalPath ( ) . local8Bit ( ) . length ( ) ) = = 0 )
{
TQDir dir ( share - > canonicalPath ( ) ) ;
if ( dir . rmdir ( dir . canonicalPath ( ) , true ) )
{
dir . cdUp ( ) ;
dir . rmdir ( dir . canonicalPath ( ) , true ) ;
}
}
m_mounted_shares . remove ( share ) ;
}
}
delete [ ] hostname ;
}
else
{
Smb4KError : : error ( ERROR_UNMOUNTING_SHARE , share - > name ( ) , m_buffer ) ;
}
}
}
emit updated ( ) ;
}
/***************************************************************************
Check if a share is already mounted
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool Smb4KMounter : : isMounted ( const TQString & name , bool userOnly )
{
TQValueList < Smb4KShare > list = findShareByName ( name ) ;
bool mounted = false ;
if ( ! list . isEmpty ( ) & & userOnly )
{
for ( TQValueList < Smb4KShare > : : ConstIterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
{
if ( ! ( * it ) . isForeign ( ) )
{
mounted = true ;
break ;
}
else
{
continue ;
}
}
}
else
{
mounted = ! list . isEmpty ( ) ;
}
return mounted ;
}
/***************************************************************************
Find a share in the list with its path
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Smb4KShare * Smb4KMounter : : findShareByPath ( const TQString & path )
{
if ( path . isEmpty ( ) | | m_mounted_shares . isEmpty ( ) )
{
return NULL ;
}
Smb4KShare * share = NULL ;
for ( TQValueListIterator < Smb4KShare * > it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
if ( TQString : : compare ( path . upper ( ) , TQString ( TQString : : fromLocal8Bit ( ( * it ) - > path ( ) , - 1 ) ) . upper ( ) ) = = 0 | |
TQString : : compare ( path . upper ( ) , TQString ( TQString : : fromLocal8Bit ( ( * it ) - > canonicalPath ( ) , - 1 ) ) . upper ( ) ) = = 0 )
{
share = * it ;
break ;
}
}
return share ;
}
/***************************************************************************
Find the list of mounts of a share
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
TQValueList < Smb4KShare > Smb4KMounter : : findShareByName ( const TQString & name )
{
TQValueList < Smb4KShare > list ;
if ( name . isEmpty ( ) | | m_mounted_shares . isEmpty ( ) )
{
return list ; // is empty
}
TQString n = name ;
for ( TQValueListIterator < Smb4KShare * > it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
if ( TQString : : compare ( ( * it ) - > name ( ) . upper ( ) , name . upper ( ) ) = = 0 | |
TQString : : compare ( ( * it ) - > name ( ) . upper ( ) , n . replace ( " " , " _ " ) . upper ( ) ) = = 0 )
{
list . append ( * ( * it ) ) ;
continue ;
}
else
{
continue ;
}
}
return list ;
}
/***************************************************************************
Returns a list of mount points that belong to broken shares
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const TQValueList < Smb4KShare * > Smb4KMounter : : getBrokenShares ( )
{
TQValueList < Smb4KShare * > broken_shares ;
for ( TQValueListIterator < Smb4KShare * > it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
if ( ( * it ) - > isBroken ( ) )
{
broken_shares . append ( * it ) ;
continue ;
}
else
{
continue ;
}
}
return broken_shares ;
}
void Smb4KMounter : : prepareForShutdown ( )
{
slotShutdown ( ) ;
}
void Smb4KMounter : : checkAccessibility ( Smb4KShare * share )
{
if ( share )
{
m_priv - > thread . setMountpoint ( share - > path ( ) ) ;
m_priv - > thread . start ( ) ;
m_priv - > thread . wait ( THREAD_WAITING_TIME ) ;
m_priv - > thread . terminate ( ) ;
m_priv - > thread . wait ( ) ;
share - > setBroken ( m_priv - > thread . isBroken ( ) ) ;
share - > setTotalDiskSpace ( m_priv - > thread . totalDiskSpace ( ) ) ;
share - > setFreeDiskSpace ( m_priv - > thread . freeDiskSpace ( ) ) ;
}
else
{
// FIXME: Should we throw an error here?
}
}
void Smb4KMounter : : timerEvent ( TQTimerEvent * )
{
if ( ! m_working & & ! m_queue . isEmpty ( ) )
{
// Tell the mounter, that it is busy.
m_working = true ;
TQString * item = m_queue . dequeue ( ) ;
int todo = item - > section ( " : " , 0 , 0 ) . toInt ( ) ;
switch ( todo )
{
case Remount :
{
remount ( ) ;
break ;
}
case Import :
{
import ( ) ;
break ;
}
case Mount :
{
emit state ( MOUNTER_MOUNTING ) ;
mount ( item - > section ( " : " , 1 , 1 ) , item - > section ( " : " , 2 , 2 ) , item - > section ( " : " , 3 , 3 ) , item - > section ( " : " , 4 , 4 ) ) ;
break ;
}
case Unmount :
{
emit state ( MOUNTER_UNMOUNTING ) ;
unmount ( item - > section ( " : " , 1 , 1 ) , ( bool ) item - > section ( " : " , 2 , 2 ) . toInt ( ) /* force */ , ( bool ) item - > section ( " : " , 3 , 3 ) . toInt ( ) /* noMessage */ ) ;
break ;
}
case UnmountAll :
{
unmountAll ( ) ;
break ;
}
default :
{
break ;
}
}
delete item ;
}
m_priv - > timerTicks + + ;
if ( m_priv - > timerTicks * timerInterval ( ) > = Smb4KSettings : : checkInterval ( ) /* msec */ & &
( ! m_working | | m_queue . isEmpty ( ) ) )
{
m_queue . enqueue ( new TQString ( TQString ( " %1: " ) . arg ( Import ) ) ) ;
m_priv - > timerTicks = 0 ;
}
}
/////////////////////////////////////////////////////////////////////////////
// TQT_SLOT IMPLEMENTATIONS
/////////////////////////////////////////////////////////////////////////////
void Smb4KMounter : : slotProcessExited ( TDEProcess * )
{
endProcess ( ) ;
}
void Smb4KMounter : : slotReceivedStdout ( TDEProcess * , char * buf , int len )
{
m_buffer . append ( TQString : : fromLocal8Bit ( buf , len ) ) ;
}
void Smb4KMounter : : slotReceivedStderr ( TDEProcess * , char * buf , int len )
{
m_buffer . append ( TQString : : fromLocal8Bit ( buf , len ) ) ;
}
void Smb4KMounter : : slotShutdown ( )
{
// Abort any action:
abort ( ) ;
// Prepare for shutdown:
if ( Smb4KSettings : : remountShares ( ) & & ! m_mounted_shares . isEmpty ( ) )
{
for ( TQValueList < Smb4KShare * > : : ConstIterator it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
optionsHandler ( ) - > remount ( * it , ! ( * it ) - > isForeign ( ) ) ;
}
}
optionsHandler ( ) - > sync ( ) ;
TQDir dir ;
dir . cd ( Smb4KSettings : : mountPrefix ( ) ) ;
TQStringList dirs = dir . entryList ( TQDir : : Dirs , TQDir : : DefaultSort ) ;
TQValueList < Smb4KShare * > broken_shares = getBrokenShares ( ) ;
for ( TQStringList : : ConstIterator it = dirs . begin ( ) ; it ! = dirs . end ( ) ; + + it )
{
if ( TQString : : compare ( * it , " . " ) ! = 0 & & TQString : : compare ( * it , " .. " ) ! = 0 )
{
bool broken = false ;
for ( TQValueListIterator < Smb4KShare * > bs = broken_shares . begin ( ) ; bs ! = broken_shares . end ( ) ; + + bs )
{
if ( tqstrncmp ( ( * bs ) - > path ( ) ,
Smb4KSettings : : mountPrefix ( ) + * it ,
( Smb4KSettings : : mountPrefix ( ) + * it ) . length ( ) ) = = 0 | |
tqstrncmp ( ( * bs ) - > canonicalPath ( ) ,
Smb4KSettings : : mountPrefix ( ) + * it ,
( Smb4KSettings : : mountPrefix ( ) + * it ) . length ( ) ) = = 0 )
{
broken = true ;
break ;
}
else
{
continue ;
}
}
if ( ! broken )
{
dir . cd ( * it ) ;
TQStringList subdirs = dir . entryList ( TQDir : : Dirs , TQDir : : DefaultSort ) ;
for ( TQStringList : : ConstIterator i = subdirs . begin ( ) ; i ! = subdirs . end ( ) ; + + i )
{
if ( TQString : : compare ( * i , " . " ) ! = 0 & & TQString : : compare ( * i , " .. " ) ! = 0 )
{
dir . rmdir ( * i ) ;
}
}
dir . cdUp ( ) ;
dir . rmdir ( * it ) ;
}
}
}
broken_shares . clear ( ) ;
if ( Smb4KSettings : : unmountSharesOnExit ( ) )
{
TQString suid_program , command ;
switch ( Smb4KSettings : : superUserProgram ( ) )
{
case Smb4KSettings : : EnumSuperUserProgram : : Sudo :
{
suid_program = Smb4KSettings : : sudo ( ) ;
break ;
}
case Smb4KSettings : : EnumSuperUserProgram : : Super :
{
suid_program = Smb4KSettings : : super ( ) ;
break ;
}
default :
{
// FIXME: Throw an error?
return ;
}
}
TDEProcess proc ;
proc . setUseShell ( true ) ;
proc . detach ( ) ;
for ( TQValueListIterator < Smb4KShare * > it = m_mounted_shares . begin ( ) ; it ! = m_mounted_shares . end ( ) ; + + it )
{
if ( ! ( * it ) - > isForeign ( ) )
{
if ( Smb4KSettings : : alwaysUseSuperUser ( ) )
{
# ifndef __FreeBSD__
command . append ( TQString ( " %1 smb4k_umount -s -t %2 " ) . arg ( suid_program ) . arg ( ( * it ) - > filesystem ( ) ) ) ;
# else
command . append ( TQString ( " %1 smb4k_umount " ) . arg ( suid_program ) ) ;
# endif
command . append ( TDEProcess : : quote ( ( * it ) - > path ( ) ) ) ;
command . append ( " ; " ) ;
}
else
{
# ifndef __FreeBSD__
command . append ( TQString ( " smb4k_umount -n -t %1 " ) . arg ( ( * it ) - > filesystem ( ) ) ) ;
# else
command . append ( " smb4k_umount " ) ;
# endif
command . append ( TDEProcess : : quote ( ( * it ) - > path ( ) ) ) ;
command . append ( " ; " ) ;
}
dir . setPath ( ( * it ) - > canonicalPath ( ) ) ;
# ifndef __FreeBSD__
command . append ( " rmdir --ignore-fail-on-non-empty " ) ;
command . append ( TDEProcess : : quote ( dir . canonicalPath ( ) ) ) ;
command . append ( " ; " ) ;
command . append ( " rmdir --ignore-fail-on-non-empty " ) ;
dir . cdUp ( ) ;
command . append ( TDEProcess : : quote ( dir . canonicalPath ( ) ) ) ;
command . append ( " ; " ) ;
# else
command . append ( " rmdir " ) ;
command . append ( TDEProcess : : quote ( dir . canonicalPath ( ) ) ) ;
command . append ( " ; " ) ;
command . append ( " rmdir " ) ;
dir . cdUp ( ) ;
command . append ( TDEProcess : : quote ( dir . canonicalPath ( ) ) ) ;
command . append ( " ; " ) ;
# endif
}
else
{
continue ;
}
}
command . truncate ( command . length ( ) - 2 ) ;
proc < < command ;
proc . start ( TDEProcess : : DontCare , TDEProcess : : NoCommunication ) ;
}
}
# include "smb4kmounter.moc"