Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
smb4k/smb4k/core/smb4ksambaoptionshandler.cpp

1560 rindas
39 KiB

/***************************************************************************
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"