diff options
Diffstat (limited to 'smb4k/core/smb4ksambaoptionshandler.cpp')
-rw-r--r-- | smb4k/core/smb4ksambaoptionshandler.cpp | 1559 |
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" |