/***************************************************************************
smb4ksambaoptionshandler - This class handles the Samba options .
- - - - - - - - - - - - - - - - - - -
begin : So Mai 14 2006
copyright : ( C ) 2006 - 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 <tqfile.h>
# include <tqtextstream.h>
# include <tqdir.h>
// KDE includes
# include <kstandarddirs.h>
# include <kprocess.h>
# include <kdebug.h>
# include <klocale.h>
// system specific includes
# include <unistd.h>
# include <sys/types.h>
# include <errno.h>
// application specific includes
# include "smb4ksambaoptionshandler.h"
# include "smb4kdefs.h"
# include "smb4kerror.h"
# include "smb4kglobal.h"
# include "smb4ksambaoptionsinfo.h"
# include "smb4kshare.h"
# include "smb4ksettings.h"
using namespace Smb4KGlobal ;
Smb4KSambaOptionsHandler : : Smb4KSambaOptionsHandler ( TQObject * parent , const char * name )
: TQObject ( parent , name )
{
// We need the directory.
KStandardDirs * stddir = new KStandardDirs ( ) ;
TQString dir = locateLocal ( " data " , " smb4k " , KGlobal : : instance ( ) ) ;
if ( ! stddir - > exists ( dir ) )
{
stddir - > makeDir ( dir ) ;
}
delete stddir ;
m_wins_server = TQString ( ) ;
}
Smb4KSambaOptionsHandler : : ~ Smb4KSambaOptionsHandler ( )
{
for ( TQValueList < Smb4KSambaOptionsInfo * > : : Iterator it = m_list . begin ( ) ;
it ! = m_list . end ( ) ; + + it )
{
delete * it ;
}
m_list . clear ( ) ;
}
const TQValueList < Smb4KSambaOptionsInfo * > & Smb4KSambaOptionsHandler : : customOptionsList ( )
{
if ( m_list . isEmpty ( ) )
{
read_options ( ) ;
}
return m_list ;
}
void Smb4KSambaOptionsHandler : : read_options ( )
{
// Clear the list before filling it (again)
if ( ! m_list . isEmpty ( ) )
{
for ( TQValueList < Smb4KSambaOptionsInfo * > : : Iterator it = m_list . begin ( ) ;
it ! = m_list . end ( ) ; + + it )
{
delete * it ;
}
m_list . clear ( ) ;
}
TQFile file ( locateLocal ( " data " , " smb4k/custom_options " , KGlobal : : instance ( ) ) ) ;
TQStringList contents ;
if ( file . open ( IO_ReadOnly ) )
{
TQTextStream ts ( & file ) ;
ts . setEncoding ( TQTextStream : : Locale ) ;
contents = TQStringList : : split ( ' \n ' , ts . read ( ) , true ) ;
file . close ( ) ;
}
else
{
if ( file . exists ( ) )
{
Smb4KError : : error ( ERROR_READING_FILE , file . name ( ) ) ;
}
return ;
}
if ( ! contents . isEmpty ( ) )
{
for ( TQStringList : : ConstIterator it = contents . begin ( ) ; it ! = contents . end ( ) ; + + it )
{
if ( ( * it ) . startsWith ( " [ " ) )
{
Smb4KSambaOptionsInfo * info = new Smb4KSambaOptionsInfo ( ( * it ) . section ( " [ " , 1 , - 1 ) . section ( " ] " , - 2 , 0 ) ) ;
for ( TQStringList : : ConstIterator i = + + it ; i ! = contents . end ( ) ; + + i )
{
if ( ( * i ) . startsWith ( " remount= " ) )
{
bool remount = TQString : : compare ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) , " true " ) = = 0 ? true : false ;
info - > setRemount ( remount ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " port= " ) )
{
int port = ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) . toInt ( ) ;
info - > setPort ( port ) ;
continue ;
}
# ifndef __FreeBSD__
else if ( ( * i ) . startsWith ( " filesystem= " ) )
{
info - > setFilesystem ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " read-write= " ) ) // Deprecated since version 0.9.0
{
info - > setWriteAccess ( TQString : : compare ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) , " true " ) = = 0 ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " write access= " ) )
{
info - > setWriteAccess ( TQString : : compare ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) , " true " ) = = 0 ) ;
continue ;
}
# endif
else if ( ( * i ) . startsWith ( " protocol= " ) )
{
info - > setProtocol ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " kerberos= " ) )
{
info - > setKerberos ( TQString : : compare ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) , " true " ) = = 0 ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " uid= " ) )
{
info - > setUID ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) ) ;
continue ;
}
else if ( ( * i ) . startsWith ( " gid= " ) )
{
info - > setGID ( ( * i ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) ) ;
continue ;
}
else if ( ( * i ) . isEmpty ( ) | | ( * i ) . stripWhiteSpace ( ) . startsWith ( " [ " ) )
{
it = i ;
break ;
}
else
{
continue ;
}
}
m_list . append ( info ) ;
}
else
{
continue ;
}
}
}
}
void Smb4KSambaOptionsHandler : : write_options ( )
{
TQString protocol_hint ;
// Determine the protocol hint specified by the user:
switch ( Smb4KSettings : : protocolHint ( ) )
{
case Smb4KSettings : : EnumProtocolHint : : Automatic :
{
// In this case the user leaves it to the net
// command to determine the right protocol.
protocol_hint = TQString ( ) ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : RPC :
{
protocol_hint = " rpc " ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : RAP :
{
protocol_hint = " rap " ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : ADS :
{
protocol_hint = " ads " ;
break ;
}
default :
{
protocol_hint = TQString ( ) ;
break ;
}
}
# ifndef __FreeBSD__
TQString default_filesystem ;
switch ( Smb4KSettings : : filesystem ( ) )
{
case Smb4KSettings : : EnumFilesystem : : CIFS :
{
default_filesystem = " cifs " ;
break ;
}
case Smb4KSettings : : EnumFilesystem : : SMBFS :
{
default_filesystem = " smbfs " ;
break ;
}
default :
{
// FIXME: Set default_filesystem to "cifs"?
break ;
}
}
bool write_access = true ;
switch ( Smb4KSettings : : writeAccess ( ) )
{
case Smb4KSettings : : EnumWriteAccess : : ReadWrite :
{
write_access = true ;
break ;
}
case Smb4KSettings : : EnumWriteAccess : : ReadOnly :
{
write_access = false ;
break ;
}
default :
{
break ;
}
}
# endif
TQFile file ( locateLocal ( " data " , " smb4k/custom_options " , KGlobal : : instance ( ) ) ) ;
if ( ! m_list . isEmpty ( ) )
{
if ( file . open ( IO_WriteOnly ) )
{
TQTextStream ts ( & file ) ;
ts . setEncoding ( TQTextStream : : Locale ) ;
for ( TQValueList < Smb4KSambaOptionsInfo * > : : ConstIterator it = m_list . begin ( ) ; it ! = m_list . end ( ) ; + + it )
{
switch ( ( * it ) - > type ( ) )
{
case Smb4KSambaOptionsInfo : : Host :
{
// Check if we need to write anything:
if ( ( * it ) - > port ( ) ! = - 1 | |
! ( * it ) - > protocol ( ) . stripWhiteSpace ( ) . isEmpty ( ) | |
( ( * it ) - > kerberos ( ) ! = Smb4KSettings : : useKerberos ( ) ) )
{
ts < < " [ " < < ( * it ) - > itemName ( ) < < " ] " < < endl ;
ts < < " port= " < < ( ( * it ) - > port ( ) ! = - 1 ? ( * it ) - > port ( ) :
Smb4KSettings : : remotePort ( ) ) < < endl ;
ts < < " kerberos= " < < ( ( * it ) - > kerberos ( ) ? " true " : " false " ) < < endl ;
ts < < " protocol= " < < ( ! ( * it ) - > protocol ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
( * it ) - > protocol ( ) : protocol_hint ) < < endl ;
}
else
{
// Do nothing
}
break ;
}
case Smb4KSambaOptionsInfo : : Share :
{
if ( ( * it ) - > port ( ) ! = - 1 | |
( * it ) - > remount ( ) | |
# ifndef __FreeBSD__
( * it ) - > kerberos ( ) ! = Smb4KSettings : : useKerberos ( ) | |
! ( * it ) - > filesystem ( ) . isEmpty ( ) | |
( * it ) - > writeAccess ( ) ! = write_access | |
# endif
! ( * it ) - > uid ( ) . isEmpty ( ) | |
! ( * it ) - > gid ( ) . isEmpty ( ) )
{
ts < < " [ " < < ( * it ) - > itemName ( ) < < " ] " < < endl ;
ts < < " port= " < < ( ( * it ) - > port ( ) ! = - 1 ? ( * it ) - > port ( ) :
Smb4KSettings : : remotePort ( ) ) < < endl ;
ts < < " remount= " < < ( ( * it ) - > remount ( ) ? " true " : " false " ) < < endl ;
# ifndef __FreeBSD__
// FreeBSD does not know Kerberos for mounting:
ts < < " kerberos= " < < ( ( * it ) - > kerberos ( ) ? " true " : " false " ) < < endl ;
ts < < " filesystem= " < < ( ! ( * it ) - > filesystem ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
( * it ) - > filesystem ( ) : default_filesystem ) < < endl ;
ts < < " write access= " < < ( ( * it ) - > writeAccess ( ) ? " true " : " false " ) < < endl ;
# endif
ts < < " uid= " < < ( ! ( * it ) - > uid ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
( * it ) - > uid ( ) : Smb4KSettings : : userID ( ) ) < < endl ;
ts < < " gid= " < < ( ! ( * it ) - > gid ( ) . stripWhiteSpace ( ) . isEmpty ( ) ?
( * it ) - > gid ( ) : Smb4KSettings : : groupID ( ) ) < < endl ;
}
else
{
// Do nothing
}
break ;
}
default :
{
break ;
}
}
ts < < endl ;
}
file . close ( ) ;
}
}
else
{
file . remove ( ) ;
}
}
void Smb4KSambaOptionsHandler : : remount ( Smb4KShare * share , bool yes )
{
if ( share )
{
Smb4KSambaOptionsInfo * info = NULL ;
if ( ( info = find_item ( share - > name ( ) ) ) )
{
info - > setRemount ( yes ) ;
}
else if ( ! info & & yes )
{
info = new Smb4KSambaOptionsInfo ( share ) ;
info - > setRemount ( yes ) ;
m_list . append ( info ) ;
}
}
}
void Smb4KSambaOptionsHandler : : sync ( )
{
write_options ( ) ;
}
Smb4KSambaOptionsInfo * Smb4KSambaOptionsHandler : : find_item ( const TQString & item , bool exactMatch )
{
// If the list is empty, we'll read the file.
if ( m_list . isEmpty ( ) )
{
read_options ( ) ;
}
TQString host = item . section ( " / " , 2 , 2 ) . stripWhiteSpace ( ) ;
Smb4KSambaOptionsInfo * info = NULL ;
if ( ! item . stripWhiteSpace ( ) . isEmpty ( ) )
{
for ( TQValueList < Smb4KSambaOptionsInfo * > : : ConstIterator it = m_list . begin ( ) ;
it ! = m_list . end ( ) ; + + it )
{
if ( TQString : : compare ( item . lower ( ) , ( * it ) - > itemName ( ) . lower ( ) ) = = 0 )
{
info = * it ;
break ;
}
else if ( TQString : : compare ( host . lower ( ) , ( * it ) - > itemName ( ) . lower ( ) ) = = 0 )
{
if ( ! info & & ! exactMatch )
{
info = * it ;
}
continue ;
}
else
{
continue ;
}
}
}
return info ;
}
const TQString Smb4KSambaOptionsHandler : : smbclientOptions ( const TQString & share )
{
// Get the global Samba options
( void ) globalSambaOptions ( ) ;
Smb4KSambaOptionsInfo * info = find_item ( share ) ;
TQString args = TQString ( ) ;
// Get the strings that are needed to put the
// argument list together:
TQString resolve_order = ( ! Smb4KSettings : : nameResolveOrder ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : nameResolveOrder ( ) ,
m_samba_options [ " name resolve order " ] ) ! = 0 ) ?
Smb4KSettings : : nameResolveOrder ( ) :
TQString ( ) ;
TQString netbios_name = ( ! Smb4KSettings : : netBIOSName ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSName ( ) ,
m_samba_options [ " netbios name " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSName ( ) :
TQString ( ) ;
TQString netbios_scope = ( ! Smb4KSettings : : netBIOSScope ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSScope ( ) ,
m_samba_options [ " netbios scope " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSScope ( ) :
TQString ( ) ;
TQString socket_options = ( ! Smb4KSettings : : socketOptions ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : socketOptions ( ) ,
m_samba_options [ " socket options " ] ) ! = 0 ) ?
Smb4KSettings : : socketOptions ( ) :
TQString ( ) ;
bool kerberos = info ?
info - > kerberos ( ) :
Smb4KSettings : : useKerberos ( ) ;
int port = info & & info - > port ( ) ! = - 1 ?
info - > port ( ) :
Smb4KSettings : : remotePort ( ) ;
// Options that are not customizable:
args . append ( ! resolve_order . isEmpty ( ) ?
TQString ( " -R '%1' " ) . tqarg ( resolve_order ) :
TQString ( ) ) ;
args . append ( ! netbios_name . isEmpty ( ) ?
TQString ( " -n '%1' " ) . tqarg ( netbios_name ) :
TQString ( ) ) ;
args . append ( ! netbios_scope . isEmpty ( ) ?
TQString ( " -i '%1' " ) . tqarg ( netbios_scope ) :
TQString ( ) ) ;
args . append ( ! socket_options . isEmpty ( ) ?
TQString ( " -O '%1' " ) . tqarg ( socket_options ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : bufferSize ( ) ! = 65520 ?
TQString ( " -b %1 " ) . tqarg ( Smb4KSettings : : bufferSize ( ) ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : machineAccount ( ) ? " -P " : TQString ( ) ) ;
switch ( Smb4KSettings : : signingState ( ) )
{
case Smb4KSettings : : EnumSigningState : : None :
{
// The user does not want this setting
// to be used.
break ;
}
case Smb4KSettings : : EnumSigningState : : On :
{
args . append ( " -S on " ) ;
break ;
}
case Smb4KSettings : : EnumSigningState : : Off :
{
args . append ( " -S off " ) ;
break ;
}
case Smb4KSettings : : EnumSigningState : : Required :
{
args . append ( " -S required " ) ;
break ;
}
default :
{
break ;
}
}
args . append ( kerberos ? " -k " : TQString ( ) ) ;
args . append ( TQString ( " -p %1 " ) . tqarg ( port ) ) ;
return args ;
}
const TQString Smb4KSambaOptionsHandler : : nmblookupOptions ( bool with_broadcast )
{
// Get the global Samba options
( void ) globalSambaOptions ( ) ;
TQString args = TQString ( ) ;
TQString netbios_name = ( ! Smb4KSettings : : netBIOSName ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSName ( ) ,
m_samba_options [ " netbios name " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSName ( ) :
TQString ( ) ;
TQString netbios_scope = ( ! Smb4KSettings : : netBIOSScope ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSScope ( ) ,
m_samba_options [ " netbios scope " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSScope ( ) :
TQString ( ) ;
TQString socket_options = ( ! Smb4KSettings : : socketOptions ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : socketOptions ( ) ,
m_samba_options [ " socket options " ] ) ! = 0 ) ?
Smb4KSettings : : socketOptions ( ) :
TQString ( ) ;
TQString domain = ( ! Smb4KSettings : : domainName ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : domainName ( ) ,
m_samba_options [ " workgroup " ] ) ! = 0 ) ?
Smb4KSettings : : domainName ( ) :
TQString ( ) ;
args . append ( ! netbios_name . isEmpty ( ) ?
TQString ( " -n '%1' " ) . tqarg ( netbios_name ) :
TQString ( ) ) ;
args . append ( ! netbios_scope . isEmpty ( ) ?
TQString ( " -i '%1' " ) . tqarg ( netbios_scope ) :
TQString ( ) ) ;
args . append ( ! socket_options . isEmpty ( ) ?
TQString ( " -O '%1' " ) . tqarg ( socket_options ) :
TQString ( ) ) ;
args . append ( ! domain . isEmpty ( ) ?
TQString ( " -W '%1' " ) . tqarg ( domain ) :
TQString ( ) ) ;
args . append ( ( ! Smb4KSettings : : broadcastAddress ( ) . isEmpty ( ) & &
with_broadcast ) ?
TQString ( " -B %1 " ) . tqarg ( Smb4KSettings : : broadcastAddress ( ) ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : usePort137 ( ) ?
" -r " :
TQString ( ) ) ;
return args ;
}
const TQString Smb4KSambaOptionsHandler : : netOptions ( int command , const TQString & networkItem , const TQString & protocol )
{
TQString args = TQString ( ) ;
Smb4KSambaOptionsInfo * info = find_item ( networkItem ) ;
TQString protocol_hint ;
// Determine the protocol hint specified by the user:
switch ( Smb4KSettings : : protocolHint ( ) )
{
case Smb4KSettings : : EnumProtocolHint : : Automatic :
{
// In this case the user leaves it to the net
// command to determine the right protocol.
protocol_hint = TQString ( ) ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : RPC :
{
protocol_hint = " rpc " ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : RAP :
{
protocol_hint = " rap " ;
break ;
}
case Smb4KSettings : : EnumProtocolHint : : ADS :
{
protocol_hint = " ads " ;
break ;
}
default :
{
protocol_hint = TQString ( ) ;
break ;
}
}
TQString default_protocol = ( info & & ! info - > protocol ( ) . isEmpty ( ) ) ?
info - > protocol ( ) :
protocol_hint ;
TQString netbios_name = ( ! Smb4KSettings : : netBIOSName ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSName ( ) ,
m_samba_options [ " netbios name " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSName ( ) :
TQString ( ) ;
TQString domain = ( ! Smb4KSettings : : domainName ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : domainName ( ) ,
m_samba_options [ " workgroup " ] ) ! = 0 ) ?
Smb4KSettings : : domainName ( ) :
TQString ( ) ;
int port = ( info & & info - > port ( ) ! = - 1 ) ?
info - > port ( ) :
Smb4KSettings : : remotePort ( ) ;
// Add command specific arguments:
switch ( command )
{
case Share :
{
// We can only use the RAP or RPC protocol here.
if ( ! protocol . stripWhiteSpace ( ) . isEmpty ( ) )
{
// Protocol can only be defined by us developers,
// and we should know what we are doing. So, no
// checks for the right protocol here:
args . append ( TQString ( " %1 " ) . tqarg ( protocol ) ) ;
}
else
{
args . append ( TQString ( " %1 " ) . tqarg ( TQString : : compare ( default_protocol , " ads " ) ! = 0 ?
default_protocol :
TQString ( ) /* FIXME: Is that the best way how to do it? */ ) ) ;
}
args . append ( " share -l " ) ;
break ;
}
case ServerDomain :
{
// NOTE: Since version 3.0.25, the command 'net rap server domain ...'
// will through an error. We have to use 'net rap server ...'. This is
// also compatible with earlier version.
// This only works with the rap protocol:
args . append ( " rap server " ) ;
break ;
}
case LookupHost :
{
// Check that the server name is present:
if ( networkItem . stripWhiteSpace ( ) . isEmpty ( ) )
{
Smb4KError : : error ( ERROR_NET_COMMAND , args . stripWhiteSpace ( ) ) ;
return args ; // still empty
}
// This lookup command takes no protocol:
args . append ( TQString ( " lookup host %1 " ) . tqarg ( networkItem ) ) ;
break ;
}
case LookupMaster :
{
// Check that the domain name is present:
if ( networkItem . stripWhiteSpace ( ) . isEmpty ( ) )
{
Smb4KError : : error ( ERROR_NET_COMMAND , args . stripWhiteSpace ( ) ) ;
return args ; // still empty
}
// This lookup command takes no protocol:
args . append ( TQString ( " lookup master '%1' " ) . tqarg ( networkItem ) ) ;
break ;
}
case Domain :
{
// This only works with the rap protocol:
args . append ( " rap domain " ) ;
break ;
}
default :
{
// Bypass the rest and return an
// empty string:
return args ;
}
}
args . append ( ! domain . isEmpty ( ) ?
TQString ( " -W '%1' " ) . tqarg ( domain ) :
TQString ( ) ) ;
args . append ( ! netbios_name . isEmpty ( ) ?
TQString ( " -n '%1' " ) . tqarg ( netbios_name ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : machineAccount ( ) ?
" -P " :
TQString ( ) ) ;
args . append ( TQString ( " -p %1 " ) . tqarg ( port ) ) ;
return args ;
}
const TQString Smb4KSambaOptionsHandler : : mountOptions ( const TQString & share )
{
Smb4KSambaOptionsInfo * info = find_item ( share ) ;
TQString args ;
// Read the global Samba options from smb.conf:
( void ) globalSambaOptions ( ) ;
// Get the strings needed to put the argument list together:
TQString uid = ( info & & ! info - > uid ( ) . isEmpty ( ) ) ?
info - > uid ( ) :
Smb4KSettings : : userID ( ) ;
TQString gid = ( info & & ! info - > gid ( ) . isEmpty ( ) ) ?
info - > gid ( ) :
Smb4KSettings : : groupID ( ) ;
TQString charset , codepage ;
switch ( Smb4KSettings : : clientCharset ( ) )
{
case Smb4KSettings : : EnumClientCharset : : default_charset :
{
charset = m_samba_options [ " unix charset " ] . lower ( ) ; // maybe empty
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_1 :
{
charset = " iso8859-1 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_2 :
{
charset = " iso8859-2 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_3 :
{
charset = " iso8859-3 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_4 :
{
charset = " iso8859-4 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_5 :
{
charset = " iso8859-5 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_6 :
{
charset = " iso8859-6 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_7 :
{
charset = " iso8859-7 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_8 :
{
charset = " iso8859-8 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_9 :
{
charset = " iso8859-9 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_13 :
{
charset = " iso8859-13 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_14 :
{
charset = " iso8859-14 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : iso8859_15 :
{
charset = " iso8859-15 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : utf8 :
{
charset = " utf8 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : koi8_r :
{
charset = " koi8-r " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : koi8_u :
{
charset = " koi8-u " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : koi8_ru :
{
charset = " koi8-ru " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : cp1251 :
{
charset = " cp1251 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : gb2312 :
{
charset = " gb2312 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : big5 :
{
charset = " big5 " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : euc_jp :
{
charset = " euc-jp " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : euc_kr :
{
charset = " euc-kr " ;
break ;
}
case Smb4KSettings : : EnumClientCharset : : tis_620 :
{
charset = " tis-620 " ;
break ;
}
default :
{
break ;
}
}
switch ( Smb4KSettings : : serverCodepage ( ) )
{
case Smb4KSettings : : EnumServerCodepage : : default_codepage :
{
codepage = m_samba_options [ " dos charset " ] . lower ( ) ; // maybe empty
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp437 :
{
codepage = " cp437 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp720 :
{
codepage = " cp720 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp737 :
{
codepage = " cp737 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp775 :
{
codepage = " cp775 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp850 :
{
codepage = " cp850 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp852 :
{
codepage = " cp852 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp855 :
{
codepage = " cp855 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp857 :
{
codepage = " cp857 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp858 :
{
codepage = " cp858 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp860 :
{
codepage = " cp860 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp861 :
{
codepage = " cp861 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp862 :
{
codepage = " cp862 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp863 :
{
codepage = " cp863 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp864 :
{
codepage = " cp864 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp865 :
{
codepage = " cp865 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp866 :
{
codepage = " cp866 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp869 :
{
codepage = " cp869 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp874 :
{
codepage = " cp874 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp932 :
{
codepage = " cp932 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp936 :
{
codepage = " cp936 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp949 :
{
codepage = " cp949 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp950 :
{
codepage = " cp950 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1250 :
{
codepage = " cp1250 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1251 :
{
codepage = " cp1251 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1252 :
{
codepage = " cp1252 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1253 :
{
codepage = " cp1253 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1254 :
{
codepage = " cp1254 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1255 :
{
codepage = " cp1255 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1256 :
{
codepage = " cp1256 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1257 :
{
codepage = " cp1257 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : cp1258 :
{
codepage = " cp1258 " ;
break ;
}
case Smb4KSettings : : EnumServerCodepage : : unicode :
{
codepage = " tqunicode " ;
break ;
}
default :
{
break ;
}
}
# ifndef __FreeBSD__
TQString netbios_name = ! Smb4KSettings : : netBIOSName ( ) . isEmpty ( ) ?
Smb4KSettings : : netBIOSName ( ) :
m_samba_options [ " netbios name " ] ;
TQString socket_options = ( ! Smb4KSettings : : socketOptions ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : socketOptions ( ) ,
m_samba_options [ " socket options " ] ) ! = 0 ) ?
Smb4KSettings : : socketOptions ( ) :
TQString ( ) ;
TQString netbios_scope = ( ! Smb4KSettings : : netBIOSScope ( ) . isEmpty ( ) & &
TQString : : compare ( Smb4KSettings : : netBIOSScope ( ) ,
m_samba_options [ " netbios scope " ] ) ! = 0 ) ?
Smb4KSettings : : netBIOSScope ( ) :
TQString ( ) ;
int port = info & & info - > port ( ) ! = - 1 ?
info - > port ( ) :
Smb4KSettings : : remotePort ( ) ;
bool kerberos = info ?
info - > kerberos ( ) :
Smb4KSettings : : useKerberos ( ) ;
bool read_write = info ?
info - > writeAccess ( ) :
( Smb4KSettings : : writeAccess ( ) = = Smb4KSettings : : EnumWriteAccess : : ReadWrite ) ;
// Compile the arguments list:
args . append ( ! netbios_name . isEmpty ( ) ?
TQString ( " netbiosname='%1', " ) . tqarg ( netbios_name ) :
TQString ( ) ) ;
args . append ( ! uid . isEmpty ( ) ?
TQString ( " uid=%1, " ) . tqarg ( uid ) :
TQString ( ) ) ;
args . append ( ! gid . isEmpty ( ) ?
TQString ( " gid=%1, " ) . tqarg ( gid ) :
TQString ( ) ) ;
args . append ( TQString ( " port=%1, " ) . tqarg ( port ) ) ;
args . append ( ! charset . isEmpty ( ) ?
TQString ( " iocharset=%1, " ) . tqarg ( charset ) :
TQString ( ) ) ;
args . append ( read_write ? " rw, " : " ro, " ) ;
switch ( Smb4KSettings : : filesystem ( ) )
{
case Smb4KSettings : : EnumFilesystem : : CIFS :
{
args . append ( ! Smb4KSettings : : fileMask ( ) . isEmpty ( ) ?
TQString ( " file_mode=%1, " ) . tqarg ( Smb4KSettings : : fileMask ( ) ) :
TQString ( ) ) ;
args . append ( ! Smb4KSettings : : directoryMask ( ) . isEmpty ( ) ?
TQString ( " dir_mode=%1, " ) . tqarg ( Smb4KSettings : : directoryMask ( ) ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : permissionChecks ( ) ?
" perm, " :
" noperm, " ) ;
args . append ( Smb4KSettings : : clientControlsIDs ( ) ?
" setuids, " :
" nosetuids, " ) ;
args . append ( Smb4KSettings : : serverInodeNumbers ( ) ?
" serverino, " :
" noserverino, " ) ;
args . append ( Smb4KSettings : : inodeDataCaching ( ) ?
" directio, " :
TQString ( ) ) ; // FIXME: Does 'nodirectio' exist?
args . append ( Smb4KSettings : : translateReservedChars ( ) ?
" mapchars, " :
" nomapchars, " ) ;
args . append ( Smb4KSettings : : noLocking ( ) ?
" nolock, " :
TQString ( ) ) ; // FIXME: Does 'lock' exist?
args . append ( ! Smb4KSettings : : customCIFSOptions ( ) . isEmpty ( ) ?
Smb4KSettings : : customCIFSOptions ( ) :
TQString ( ) ) ;
break ;
}
case Smb4KSettings : : EnumFilesystem : : SMBFS :
{
args . append ( ! socket_options . isEmpty ( ) ?
TQString ( " sockopt='%1', " ) . tqarg ( socket_options ) :
TQString ( ) ) ;
args . append ( ! netbios_scope . isEmpty ( ) ?
TQString ( " scope=%1, " ) . tqarg ( netbios_scope ) :
TQString ( ) ) ;
args . append ( ! codepage . isEmpty ( ) ?
TQString ( " codepage=%1, " ) . tqarg ( codepage ) :
TQString ( ) ) ;
args . append ( ! Smb4KSettings : : fileMask ( ) . isEmpty ( ) ?
TQString ( " fmask=%1, " ) . tqarg ( Smb4KSettings : : fileMask ( ) ) :
TQString ( ) ) ;
args . append ( ! Smb4KSettings : : directoryMask ( ) . isEmpty ( ) ?
TQString ( " dmask=%1, " ) . tqarg ( Smb4KSettings : : directoryMask ( ) ) :
TQString ( ) ) ;
args . append ( kerberos ? " krb, " : TQString ( ) ) ;
args . append ( Smb4KSettings : : cachingTime ( ) ! = 1000 ?
TQString ( " ttl=%1, " ) . tqarg ( Smb4KSettings : : cachingTime ( ) ) :
TQString ( ) ) ;
args . append ( Smb4KSettings : : unicodeSupport ( ) ?
" tqunicode, " :
TQString ( ) ) ;
args . append ( Smb4KSettings : : largeFileSystemSupport ( ) ?
" lfs, " :
TQString ( ) ) ;
break ;
}
default :
{
break ;
}
}
# else
// Compile the arguments list:
args . append ( ! uid . isEmpty ( ) ?
TQString ( " -u %1 " ) . tqarg ( uid ) :
TQString ( ) ) ;
args . append ( ! gid . isEmpty ( ) ?
TQString ( " -g %1 " ) . tqarg ( gid ) :
TQString ( ) ) ;
args . append ( ! charset . isEmpty ( ) & & ! codepage . isEmpty ( ) ?
TQString ( " -E %1:%2 " ) . tqarg ( charset , codepage ) :
TQString ( ) ) ;
args . append ( ! Smb4KSettings : : fileMask ( ) . isEmpty ( ) ?
TQString ( " -f %1 " ) . tqarg ( Smb4KSettings : : fileMask ( ) ) :
TQString ( ) ) ;
args . append ( ! Smb4KSettings : : directoryMask ( ) . isEmpty ( ) ?
TQString ( " -d %1 " ) . tqarg ( Smb4KSettings : : directoryMask ( ) ) :
TQString ( ) ) ;
// NOTE: Under FreeBSD the port must be managed by the mounter.
// FIXME: If the manual page was of more use, we could probably implement
// more of the arguments that are available for mount_smbfs.
# endif
return args ;
}
void Smb4KSambaOptionsHandler : : read_smb_conf ( )
{
// Clear the options list before reading.
m_samba_options . clear ( ) ;
TQStringList paths ;
paths < < " /etc " ;
paths < < " /etc/samba " ;
paths < < " /usr/local/etc " ;
paths < < " /usr/local/etc/samba " ;
TQFile f ( " smb.conf " ) ;
TQStringList contents ;
// Locate the file and read its contents:
for ( TQStringList : : Iterator it = paths . begin ( ) ; it ! = paths . end ( ) ; + + it )
{
TQDir : : setCurrent ( * it ) ;
if ( f . exists ( ) )
{
if ( f . open ( IO_ReadOnly ) )
{
TQTextStream ts ( & f ) ;
ts . setEncoding ( TQTextStream : : Locale ) ;
contents = TQStringList : : split ( ' \n ' , ts . read ( ) , false ) ;
}
f . close ( ) ;
break ;
}
else
{
continue ;
}
}
// Process the file contents.
for ( TQStringList : : Iterator it = contents . erase ( contents . begin ( ) , + + ( contents . find ( " [global] " ) ) ) ; it ! = contents . end ( ) ; + + it )
{
if ( ( * it ) . stripWhiteSpace ( ) . startsWith ( " # " ) | | ( * it ) . stripWhiteSpace ( ) . startsWith ( " ; " ) )
{
* it = TQString ( ) ;
}
else if ( ( * it ) . stripWhiteSpace ( ) . startsWith ( " include " ) )
{
// Put the contents of the included at this position.
TQString file = ( * it ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) ;
* it = TQString ( ) ;
f . setName ( file ) ;
TQStringList include ;
if ( f . exists ( ) )
{
if ( f . open ( IO_ReadOnly ) )
{
TQTextStream ts ( & f ) ;
ts . setEncoding ( TQTextStream : : Locale ) ;
include = TQStringList : : split ( ' \n ' , ts . read ( ) , false ) ;
}
f . close ( ) ;
}
for ( TQStringList : : Iterator i = include . begin ( ) ; i ! = include . end ( ) ; + + i )
{
if ( ! ( * i ) . stripWhiteSpace ( ) . isEmpty ( ) )
{
contents . insert ( it , * i ) ;
continue ;
}
else
{
continue ;
}
}
continue ;
}
else if ( ( * it ) . startsWith ( " [ " ) )
{
contents . erase ( it , contents . end ( ) ) ;
break ;
}
else
{
continue ;
}
}
contents . remove ( TQString ( ) ) ;
// Write all options into the map:
for ( TQStringList : : ConstIterator it = contents . begin ( ) ; it ! = contents . end ( ) ; + + it )
{
TQString key = ( * it ) . section ( " = " , 0 , 0 ) . stripWhiteSpace ( ) . lower ( ) ;
m_samba_options [ key ] = TQString ( ( * it ) . section ( " = " , 1 , 1 ) . stripWhiteSpace ( ) . upper ( ) ) ;
}
// Post-processing. Some values should be entered with their defaults, if they are
// not already present.
if ( ! m_samba_options . contains ( " netbios name " ) )
{
size_t hostnamelen = 255 ;
char * hostname = new char [ hostnamelen ] ;
if ( gethostname ( hostname , hostnamelen ) = = - 1 )
{
int error = errno ;
Smb4KError : : error ( ERROR_GETTING_HOSTNAME , TQString ( ) , strerror ( error ) ) ;
}
else
{
m_samba_options [ " netbios name " ] = ( TQString ( " %1 " ) . tqarg ( hostname ) ) . upper ( ) ;
}
delete [ ] hostname ;
}
}
const TQMap < TQString , TQString > & Smb4KSambaOptionsHandler : : globalSambaOptions ( )
{
if ( m_samba_options . isEmpty ( ) )
{
read_smb_conf ( ) ;
}
return m_samba_options ;
}
const TQString & Smb4KSambaOptionsHandler : : winsServer ( )
{
if ( m_wins_server . isEmpty ( ) )
{
( void ) globalSambaOptions ( ) ;
if ( ! m_samba_options [ " wins server " ] . isEmpty ( ) )
{
m_wins_server = m_samba_options [ " wins server " ] ;
}
else if ( ! m_samba_options [ " wins support " ] . isEmpty ( ) & &
( TQString : : compare ( m_samba_options [ " wins support " ] . lower ( ) , " yes " ) = = 0 | |
TQString : : compare ( m_samba_options [ " wins support " ] . lower ( ) , " true " ) = = 0 ) )
{
m_wins_server = " 127.0.0.1 " ;
}
}
return m_wins_server ;
}
void Smb4KSambaOptionsHandler : : addItem ( Smb4KSambaOptionsInfo * info , bool s )
{
Smb4KSambaOptionsInfo * item = find_item ( info - > itemName ( ) ) ;
if ( item & & TQString : : compare ( item - > itemName ( ) . lower ( ) , info - > itemName ( ) . lower ( ) ) = = 0 )
{
item - > setPort ( info - > port ( ) ) ;
# ifndef __FreeBSD__
item - > setFilesystem ( info - > filesystem ( ) ) ;
item - > setWriteAccess ( info - > writeAccess ( ) ) ;
# endif
item - > setRemount ( info - > remount ( ) ) ;
item - > setProtocol ( info - > protocol ( ) ) ;
item - > setKerberos ( info - > kerberos ( ) ) ;
item - > setUID ( info - > uid ( ) ) ;
item - > setGID ( info - > gid ( ) ) ;
delete info ;
}
else
{
m_list . append ( info ) ;
}
if ( s )
{
sync ( ) ;
}
}
void Smb4KSambaOptionsHandler : : removeItem ( const TQString & name , bool s )
{
Smb4KSambaOptionsInfo * item = find_item ( name ) ;
if ( item & & TQString : : compare ( item - > itemName ( ) . lower ( ) , name . lower ( ) ) = = 0 )
{
m_list . remove ( item ) ;
delete item ;
}
if ( s )
{
sync ( ) ;
}
}
# include "smb4ksambaoptionshandler.moc"