summaryrefslogtreecommitdiffstats
path: root/smb4k/core/smb4ksambaoptionshandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'smb4k/core/smb4ksambaoptionshandler.cpp')
-rw-r--r--smb4k/core/smb4ksambaoptionshandler.cpp1559
1 files changed, 1559 insertions, 0 deletions
diff --git a/smb4k/core/smb4ksambaoptionshandler.cpp b/smb4k/core/smb4ksambaoptionshandler.cpp
new file mode 100644
index 0000000..e31648d
--- /dev/null
+++ b/smb4k/core/smb4ksambaoptionshandler.cpp
@@ -0,0 +1,1559 @@
+/***************************************************************************
+ 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 *
+ ***************************************************************************/
+
+// Qt includes
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdir.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( QObject *parent, const char *name )
+: QObject( parent, name )
+{
+ // We need the directory.
+ KStandardDirs *stddir = new KStandardDirs();
+ QString dir = locateLocal( "data", "smb4k", KGlobal::instance() );
+
+ if ( !stddir->exists( dir ) )
+ {
+ stddir->makeDir( dir );
+ }
+
+ delete stddir;
+
+ m_wins_server = QString::null;
+}
+
+
+Smb4KSambaOptionsHandler::~Smb4KSambaOptionsHandler()
+{
+ for ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_list.clear();
+}
+
+
+const QValueList<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 ( QValueList<Smb4KSambaOptionsInfo *>::Iterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ delete *it;
+ }
+
+ m_list.clear();
+ }
+
+ QFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
+
+ QStringList contents;
+
+ if ( file.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), true );
+
+ file.close();
+ }
+ else
+ {
+ if ( file.exists() )
+ {
+ Smb4KError::error( ERROR_READING_FILE, file.name() );
+ }
+
+ return;
+ }
+
+ if ( !contents.isEmpty() )
+ {
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ if ( (*it).startsWith( "[" ) )
+ {
+ Smb4KSambaOptionsInfo *info = new Smb4KSambaOptionsInfo( (*it).section( "[", 1, -1 ).section( "]", -2, 0 ) );
+
+ for ( QStringList::ConstIterator i = ++it; i != contents.end(); ++i )
+ {
+ if ( (*i).startsWith( "remount=" ) )
+ {
+ bool remount = QString::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( QString::compare( (*i).section( "=", 1, 1 ).stripWhiteSpace(), "true" ) == 0 );
+
+ continue;
+ }
+ else if ( (*i).startsWith( "write access=" ) )
+ {
+ info->setWriteAccess( QString::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( QString::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()
+{
+ QString 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 = QString::null;
+
+ 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 = QString::null;
+
+ break;
+ }
+ }
+
+#ifndef __FreeBSD__
+
+ QString 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
+
+ QFile file( locateLocal( "data", "smb4k/custom_options", KGlobal::instance() ) );
+
+ if ( !m_list.isEmpty() )
+ {
+ if ( file.open( IO_WriteOnly ) )
+ {
+ QTextStream ts( &file );
+ ts.setEncoding( QTextStream::Locale );
+
+ for ( QValueList<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 QString &item, bool exactMatch )
+{
+ // If the list is empty, we'll read the file.
+ if ( m_list.isEmpty() )
+ {
+ read_options();
+ }
+
+ QString host = item.section( "/", 2, 2 ).stripWhiteSpace();
+
+ Smb4KSambaOptionsInfo *info = NULL;
+
+ if ( !item.stripWhiteSpace().isEmpty() )
+ {
+ for ( QValueList<Smb4KSambaOptionsInfo *>::ConstIterator it = m_list.begin();
+ it != m_list.end(); ++it )
+ {
+ if ( QString::compare( item.lower(), (*it)->itemName().lower() ) == 0 )
+ {
+ info = *it;
+
+ break;
+ }
+ else if ( QString::compare( host.lower(), (*it)->itemName().lower() ) == 0 )
+ {
+ if ( !info && !exactMatch )
+ {
+ info = *it;
+ }
+
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ }
+
+ return info;
+}
+
+
+const QString Smb4KSambaOptionsHandler::smbclientOptions( const QString &share )
+{
+ // Get the global Samba options
+ (void) globalSambaOptions();
+
+ Smb4KSambaOptionsInfo *info = find_item( share );
+ QString args = QString::null;
+
+ // Get the strings that are needed to put the
+ // argument list together:
+ QString resolve_order = (!Smb4KSettings::nameResolveOrder().isEmpty() &&
+ QString::compare( Smb4KSettings::nameResolveOrder(),
+ m_samba_options["name resolve order"] ) != 0) ?
+ Smb4KSettings::nameResolveOrder() :
+ QString::null;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ 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() ?
+ QString( " -R '%1'" ).arg( resolve_order ) :
+ QString::null );
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( " -i '%1'" ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !socket_options.isEmpty() ?
+ QString( " -O '%1'" ).arg( socket_options ) :
+ QString::null );
+
+ args.append( Smb4KSettings::bufferSize() != 65520 ?
+ QString( " -b %1" ).arg( Smb4KSettings::bufferSize() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::machineAccount() ? " -P" : QString::null );
+
+ 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" : QString::null );
+
+ args.append( QString( " -p %1" ).arg( port ) );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::nmblookupOptions( bool with_broadcast )
+{
+ // Get the global Samba options
+ (void) globalSambaOptions();
+
+ QString args = QString::null;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ QString domain = (!Smb4KSettings::domainName().isEmpty() &&
+ QString::compare( Smb4KSettings::domainName(),
+ m_samba_options["workgroup"] ) != 0) ?
+ Smb4KSettings::domainName() :
+ QString::null;
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( " -i '%1'" ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !socket_options.isEmpty() ?
+ QString( " -O '%1'" ).arg( socket_options ) :
+ QString::null );
+
+ args.append( !domain.isEmpty() ?
+ QString( " -W '%1'" ).arg( domain ) :
+ QString::null );
+
+ args.append( (!Smb4KSettings::broadcastAddress().isEmpty() &&
+ with_broadcast) ?
+ QString( " -B %1" ).arg( Smb4KSettings::broadcastAddress() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::usePort137() ?
+ " -r" :
+ QString::null );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::netOptions( int command, const QString &networkItem, const QString &protocol )
+{
+ QString args = QString::null;
+
+ Smb4KSambaOptionsInfo *info = find_item( networkItem );
+
+ QString 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 = QString::null;
+
+ 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 = QString::null;
+
+ break;
+ }
+ }
+
+ QString default_protocol = (info && !info->protocol().isEmpty()) ?
+ info->protocol() :
+ protocol_hint;
+
+ QString netbios_name = (!Smb4KSettings::netBIOSName().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSName(),
+ m_samba_options["netbios name"] ) != 0) ?
+ Smb4KSettings::netBIOSName() :
+ QString::null;
+
+ QString domain = (!Smb4KSettings::domainName().isEmpty() &&
+ QString::compare( Smb4KSettings::domainName(),
+ m_samba_options["workgroup"] ) != 0) ?
+ Smb4KSettings::domainName() :
+ QString::null;
+
+ 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( QString( " %1" ).arg( protocol ) );
+ }
+ else
+ {
+ args.append( QString( " %1" ).arg( QString::compare( default_protocol, "ads" ) != 0 ?
+ default_protocol :
+ QString::null /* 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( QString( " lookup host %1" ).arg( 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( QString( " lookup master '%1'" ).arg( 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() ?
+ QString( " -W '%1'" ).arg( domain ) :
+ QString::null );
+
+ args.append( !netbios_name.isEmpty() ?
+ QString( " -n '%1'" ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( Smb4KSettings::machineAccount() ?
+ " -P" :
+ QString::null );
+
+ args.append( QString( " -p %1" ).arg( port ) );
+
+ return args;
+}
+
+
+const QString Smb4KSambaOptionsHandler::mountOptions( const QString &share )
+{
+ Smb4KSambaOptionsInfo *info = find_item( share );
+ QString args;
+
+ // Read the global Samba options from smb.conf:
+ (void) globalSambaOptions();
+
+ // Get the strings needed to put the argument list together:
+ QString uid = (info && !info->uid().isEmpty()) ?
+ info->uid() :
+ Smb4KSettings::userID();
+
+ QString gid = (info && !info->gid().isEmpty()) ?
+ info->gid() :
+ Smb4KSettings::groupID();
+
+ QString 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 = "unicode";
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#ifndef __FreeBSD__
+
+ QString netbios_name = !Smb4KSettings::netBIOSName().isEmpty() ?
+ Smb4KSettings::netBIOSName() :
+ m_samba_options["netbios name"];
+
+ QString socket_options = (!Smb4KSettings::socketOptions().isEmpty() &&
+ QString::compare( Smb4KSettings::socketOptions(),
+ m_samba_options["socket options"] ) != 0) ?
+ Smb4KSettings::socketOptions() :
+ QString::null;
+
+ QString netbios_scope = (!Smb4KSettings::netBIOSScope().isEmpty() &&
+ QString::compare( Smb4KSettings::netBIOSScope(),
+ m_samba_options["netbios scope"] ) != 0) ?
+ Smb4KSettings::netBIOSScope() :
+ QString::null;
+
+ 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() ?
+ QString( "netbiosname='%1'," ).arg( netbios_name ) :
+ QString::null );
+
+ args.append( !uid.isEmpty() ?
+ QString( "uid=%1," ).arg( uid ) :
+ QString::null );
+
+ args.append( !gid.isEmpty() ?
+ QString( "gid=%1," ).arg( gid ) :
+ QString::null );
+
+ args.append( QString( "port=%1," ).arg( port ) );
+
+ args.append( !charset.isEmpty() ?
+ QString( "iocharset=%1," ).arg( charset ) :
+ QString::null );
+
+ args.append( read_write ? "rw," : "ro," );
+
+ switch ( Smb4KSettings::filesystem() )
+ {
+ case Smb4KSettings::EnumFilesystem::CIFS:
+ {
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( "file_mode=%1," ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( "dir_mode=%1," ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::permissionChecks() ?
+ "perm," :
+ "noperm," );
+
+ args.append( Smb4KSettings::clientControlsIDs() ?
+ "setuids," :
+ "nosetuids," );
+
+ args.append( Smb4KSettings::serverInodeNumbers() ?
+ "serverino," :
+ "noserverino," );
+
+ args.append( Smb4KSettings::inodeDataCaching() ?
+ "directio," :
+ QString::null ); // FIXME: Does 'nodirectio' exist?
+
+ args.append( Smb4KSettings::translateReservedChars() ?
+ "mapchars," :
+ "nomapchars," );
+
+ args.append( Smb4KSettings::noLocking() ?
+ "nolock," :
+ QString::null ); // FIXME: Does 'lock' exist?
+
+ args.append( !Smb4KSettings::customCIFSOptions().isEmpty() ?
+ Smb4KSettings::customCIFSOptions() :
+ QString::null );
+
+ break;
+ }
+ case Smb4KSettings::EnumFilesystem::SMBFS:
+ {
+ args.append( !socket_options.isEmpty() ?
+ QString( "sockopt='%1'," ).arg( socket_options ) :
+ QString::null );
+
+ args.append( !netbios_scope.isEmpty() ?
+ QString( "scope=%1," ).arg( netbios_scope ) :
+ QString::null );
+
+ args.append( !codepage.isEmpty() ?
+ QString( "codepage=%1," ).arg( codepage ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( "fmask=%1," ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( "dmask=%1," ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ args.append( kerberos ? "krb," : QString::null );
+
+ args.append( Smb4KSettings::cachingTime() != 1000 ?
+ QString( "ttl=%1," ).arg( Smb4KSettings::cachingTime() ) :
+ QString::null );
+
+ args.append( Smb4KSettings::unicodeSupport() ?
+ "unicode," :
+ QString::null );
+
+ args.append( Smb4KSettings::largeFileSystemSupport() ?
+ "lfs," :
+ QString::null );
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+#else
+
+ // Compile the arguments list:
+ args.append( !uid.isEmpty() ?
+ QString( " -u %1" ).arg( uid ) :
+ QString::null );
+
+ args.append( !gid.isEmpty() ?
+ QString( " -g %1" ).arg( gid ) :
+ QString::null );
+
+ args.append( !charset.isEmpty() && !codepage.isEmpty() ?
+ QString( " -E %1:%2" ).arg( charset, codepage ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::fileMask().isEmpty() ?
+ QString( " -f %1" ).arg( Smb4KSettings::fileMask() ) :
+ QString::null );
+
+ args.append( !Smb4KSettings::directoryMask().isEmpty() ?
+ QString( " -d %1" ).arg( Smb4KSettings::directoryMask() ) :
+ QString::null );
+
+ // 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();
+
+ QStringList paths;
+ paths << "/etc";
+ paths << "/etc/samba";
+ paths << "/usr/local/etc";
+ paths << "/usr/local/etc/samba";
+
+ QFile f( "smb.conf" );
+
+ QStringList contents;
+
+ // Locate the file and read its contents:
+ for ( QStringList::Iterator it = paths.begin(); it != paths.end(); ++it )
+ {
+ QDir::setCurrent( *it );
+
+ if ( f.exists() )
+ {
+ if ( f.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &f );
+ ts.setEncoding( QTextStream::Locale );
+
+ contents = QStringList::split( '\n', ts.read(), false );
+ }
+
+ f.close();
+
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ // Process the file contents.
+ for ( QStringList::Iterator it = contents.erase( contents.begin(), ++(contents.find( "[global]" )) ); it != contents.end(); ++it )
+ {
+ if ( (*it).stripWhiteSpace().startsWith( "#" ) || (*it).stripWhiteSpace().startsWith( ";" ) )
+ {
+ *it = QString::null;
+ }
+ else if ( (*it).stripWhiteSpace().startsWith( "include" ) )
+ {
+ // Put the contents of the included at this position.
+ QString file = (*it).section( "=", 1, 1 ).stripWhiteSpace();
+ *it = QString::null;
+ f.setName( file );
+
+ QStringList include;
+
+ if ( f.exists() )
+ {
+ if ( f.open( IO_ReadOnly ) )
+ {
+ QTextStream ts( &f );
+ ts.setEncoding( QTextStream::Locale );
+
+ include = QStringList::split( '\n', ts.read(), false );
+ }
+
+ f.close();
+ }
+
+ for ( QStringList::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( QString::null );
+
+ // Write all options into the map:
+ for ( QStringList::ConstIterator it = contents.begin(); it != contents.end(); ++it )
+ {
+ QString key = (*it).section( "=", 0, 0 ).stripWhiteSpace().lower();
+ m_samba_options[key] = QString( (*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, QString::null, strerror( error ) );
+ }
+ else
+ {
+ m_samba_options["netbios name"] = ( QString( "%1" ).arg( hostname ) ).upper();
+ }
+
+ delete [] hostname;
+ }
+}
+
+
+const QMap<QString,QString> &Smb4KSambaOptionsHandler::globalSambaOptions()
+{
+ if ( m_samba_options.isEmpty() )
+ {
+ read_smb_conf();
+ }
+
+ return m_samba_options;
+}
+
+
+const QString &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() &&
+ (QString::compare( m_samba_options["wins support"].lower(), "yes" ) == 0 ||
+ QString::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 && QString::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 QString &name, bool s )
+{
+ Smb4KSambaOptionsInfo *item = find_item( name );
+
+ if ( item && QString::compare( item->itemName().lower(), name.lower() ) == 0 )
+ {
+ m_list.remove( item );
+ delete item;
+ }
+
+ if ( s )
+ {
+ sync();
+ }
+}
+
+#include "smb4ksambaoptionshandler.moc"