/*************************************************************************** smb4kcore - The main core class of Smb4K. ------------------- begin : Do Apr 8 2004 copyright : (C) 2004-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 #include #include // KDE includes #include #include #include #include #include #include #include #include #include #include // system includes #include // application specific includes #include "smb4kcore.h" #include "smb4kdefs.h" #include "smb4kerror.h" #include "smb4kglobal.h" #include "smb4knetworkitems.h" #include "smb4kshare.h" #include "smb4ksambaoptionshandler.h" #include "smb4ksettings.h" using namespace Smb4KGlobal; Smb4KCore *Smb4KCore::m_self = 0; static KStaticDeleter staticSmb4KCoreDeleter; Smb4KCore::Smb4KCore() : TQObject() { // Set default values for settings that depend on the system // Smb4K is running on: setDefaultSettings(); // Search for the programs that are needed by Smb4K: searchPrograms(); m_fileIO = new Smb4KFileIO( this, "CoreFileIO" ); m_scanner = new Smb4KScanner( &m_workgroups, &m_hosts, this, "CoreScanner" ); m_mounter = new Smb4KMounter( this, "CoreMounter" ); m_bookmarkHandler = new Smb4KBookmarkHandler( &m_hosts, this, "CoreBookmarkHandler" ); m_print = new Smb4KPrint( this, "CorePrinterHandler" ); m_synchronizer = new Smb4KSynchronizer( this, "CoreSynchronizer" ); m_previewer = new Smb4KPreviewer( this, "CorePreviewer" ); m_scanner_state = SCANNER_STOP; m_mounter_state = MOUNTER_STOP; m_print_state = PRINT_STOP; m_syncer_state = SYNCHRONIZER_STOP; m_previewer_state = PREVIEWER_STOP; // Connections: connect( m_scanner, TQT_SIGNAL( state( int ) ), this, TQT_SLOT( slotSetScannerState( int ) ) ); connect( m_mounter, TQT_SIGNAL( state( int ) ), this, TQT_SLOT( slotSetMounterState( int ) ) ); connect( m_print, TQT_SIGNAL( state( int ) ), this, TQT_SLOT( slotSetPrinterHandlerState( int ) ) ); connect( m_synchronizer, TQT_SIGNAL( state( int ) ), this, TQT_SLOT( slotSetSynchronizerState( int ) ) ); connect( m_previewer, TQT_SIGNAL( state( int ) ), this, TQT_SLOT( slotSetSynchronizerState( int ) ) ); connect( kapp, TQT_SIGNAL( shutDown() ), this, TQT_SLOT( slotShutdown() ) ); } Smb4KCore::~Smb4KCore() { // Do not call abort() here. This will most likely lead // to crashes. // Clear the list of workgroups. for ( TQValueList::Iterator it = m_workgroups.begin(); it != m_workgroups.end(); ++it ) { delete *it; } m_workgroups.clear(); // Clear the list of hosts. for ( TQValueList::Iterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) { delete *it; } m_hosts.clear(); if ( m_self == this ) { staticSmb4KCoreDeleter.setObject( m_self, 0, false ); } } Smb4KCore *Smb4KCore::self() { if ( !m_self ) { staticSmb4KCoreDeleter.setObject( m_self, new Smb4KCore() ); } return m_self; } void Smb4KCore::init() { // Start the core. m_scanner->init(); m_mounter->init(); } /**************************************************************************** Returns a bool that tells the program whether a core process is running. ****************************************************************************/ bool Smb4KCore::isRunning() { if ( self()->m_scanner->isRunning() || self()->m_mounter->isRunning() || self()->m_print->isRunning() || self()->m_synchronizer->isRunning() || self()->m_previewer->isRunning() ) { return true; } else { return false; } } /**************************************************************************** Sets the current state of the core. ****************************************************************************/ void Smb4KCore::setCurrentState( int state ) { if ( state != SCANNER_STOP && state != MOUNTER_STOP && state != PRINT_STOP && state != SYNCHRONIZER_STOP && state != PREVIEWER_STOP ) { m_current_state = state; } else { if ( !m_scanner->isRunning() && !m_mounter->isRunning() && !m_print->isRunning() && !m_synchronizer->isRunning() && !m_previewer->isRunning() ) { m_current_state = CORE_STOP; } else { if ( m_scanner->isRunning() ) { m_current_state = m_scanner_state; } else if ( m_print->isRunning() ) { m_current_state = m_print_state; } else if ( m_mounter->isRunning() ) { m_current_state = m_mounter_state; } else if ( m_synchronizer->isRunning() ) { m_current_state = m_syncer_state; } else if ( m_previewer->isRunning() ) { m_current_state = m_previewer_state; } } } } /**************************************************************************** Aborts any process of the core. ****************************************************************************/ void Smb4KCore::abort() { self()->m_scanner->abort(); self()->m_mounter->abort(); self()->m_print->abort(); self()->m_synchronizer->abort(); self()->m_previewer->abort(); } /**************************************************************************** Opens the given URL. ****************************************************************************/ void Smb4KCore::open( Smb4KShare *share, int openWith ) { if ( !share || share->isBroken() ) { return; } #if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR <= 3 && KDE_VERSION_RELEASE <= 92 if ( TQString::compare( share->filesystem(), "cifs" ) == 0 ) { if( KMessageBox::warningContinueCancel( (TQWidget *)this, i18n( "Up to KDE 3.3.x, KIO and Konqueror cannot handle CIFS shares. Konqueror will hang if you try to access it.\nDo you want to continue?" ) ) == KMessageBox::Cancel ) { return; } } #endif switch ( openWith ) { case Konqueror: { KURL url; url.setPath( share->canonicalPath() ); (void) new KRun( url, 0, true, true ); break; } case Konsole: { if ( Smb4KSettings::konsole().isEmpty() ) { Smb4KError::error( ERROR_COMMAND_NOT_FOUND, "konsole" ); } else { KRun::runCommand( "konsole --workdir "+share->canonicalPath() ); } break; } default: { break; } } } /**************************************************************************** Searches for the programs needed by Smb4K ****************************************************************************/ void Smb4KCore::searchPrograms() { // Remove the group "Programs" and reread the // configuration: Smb4KSettings::self()->config()->deleteGroup( "Programs" ); Smb4KSettings::self()->readConfig(); // List of paths that should be searched. TQStringList path_list = TQStringList::split( ":", TQString( "%1" ).tqarg( getenv( "PATH" ) ), false ); if ( path_list.find( "/sbin" ) == path_list.end() ) { path_list << "/sbin"; } if ( path_list.find( "/usr/sbin" ) == path_list.end() ) { path_list << "/usr/sbin"; } if ( path_list.find( "/usr/local/sbin" ) == path_list.end() ) { path_list << "/usr/local/sbin"; } // Put all programs that are needed by Smb4K // into the map below: TQMap program_list; TQMap program_paths; // Mandatory programs: program_list.insert( "grep", false ); program_list.insert( "awk", false ); program_list.insert( "sed", false ); program_list.insert( "xargs", false ); program_list.insert( "rmdir", false ); program_list.insert( "nmblookup", false ); program_list.insert( "smbclient", false ); program_list.insert( "smbspool", false ); program_list.insert( "net", false ); #ifndef __FreeBSD__ program_list.insert( "mount.cifs", false ); program_list.insert( "umount.cifs", false ); program_list.insert( "smbmount", false ); program_list.insert( "smbumount", false ); program_list.insert( "mount", false ); #else program_list.insert( "mount_smbfs", false ); program_list.insert( "smbutil", false ); #endif program_list.insert( "umount", false ); program_list.insert( "smb4k_mount", false ); program_list.insert( "smb4k_umount", false ); program_list.insert( "smb4k_kill", false ); program_list.insert( "smb4k_cat", false ); program_list.insert( "smb4k_mv", false ); // Optional programs program_list.insert( "super", false ); program_list.insert( "sudo", false ); program_list.insert( "dvips", false ); program_list.insert( "enscript", false ); program_list.insert( "rsync", false ); program_list.insert( "konsole", false ); for ( TQStringList::ConstIterator it = path_list.begin(); it != path_list.end(); ++it ) { TQDir::setCurrent( *it ); for ( TQMap::Iterator p = program_list.begin(); p != program_list.end(); ++p ) { if ( p.data() == false ) // not located yet { if ( TQFile::exists( p.key() ) ) { program_paths.insert( p.key(), TQDir::currentDirPath()+TQDir::separator()+p.key() ); program_list[ p.key() ] = true; } else { continue; } } else { continue; } } } // Find out if Smb4K is to be starting up at all: TQStringList missing; if ( !program_list["grep"] ) { missing.append( "grep" ); } else { Smb4KSettings::self()->grepItem()->setDefaultValue( program_paths["grep"] ); if ( Smb4KSettings::grep().isEmpty() ) { Smb4KSettings::self()->grepItem()->setDefault(); } } if ( !program_list["awk"] ) { missing.append( "awk" ); } else { Smb4KSettings::self()->awkItem()->setDefaultValue( program_paths["awk"] ); if ( Smb4KSettings::awk().isEmpty() ) { Smb4KSettings::self()->awkItem()->setDefault(); } } if ( !program_list["sed"] ) { missing.append( "sed" ); } else { Smb4KSettings::self()->sedItem()->setDefaultValue( program_paths["sed"] ); if ( Smb4KSettings::sed().isEmpty() ) { Smb4KSettings::self()->sedItem()->setDefault(); } } if ( !program_list["xargs"] ) { missing.append( "xargs" ); } else { Smb4KSettings::self()->xargsItem()->setDefaultValue( program_paths["xargs"] ); if ( Smb4KSettings::xargs().isEmpty() ) { Smb4KSettings::self()->xargsItem()->setDefault(); } } if ( !program_list["rmdir"] ) { missing.append( "rmdir" ); } else { Smb4KSettings::self()->rmdirItem()->setDefaultValue( program_paths["rmdir"] ); if ( Smb4KSettings::rmdir().isEmpty() ) { Smb4KSettings::self()->rmdirItem()->setDefault(); } } if ( !program_list["nmblookup"] ) { missing.append( "nmblookup" ); } else { Smb4KSettings::self()->nmblookupItem()->setDefaultValue( program_paths["nmblookup"] ); if ( Smb4KSettings::nmblookup().isEmpty() ) { Smb4KSettings::self()->nmblookupItem()->setDefault(); } } if ( !program_list["smbclient"] ) { missing.append( "smbclient" ); } else { Smb4KSettings::self()->smbclientItem()->setDefaultValue( program_paths["smbclient"] ); if ( Smb4KSettings::smbclient().isEmpty() ) { Smb4KSettings::self()->smbclientItem()->setDefault(); } } if ( !program_list["smbspool"] ) { missing.append( "smbspool" ); } else { Smb4KSettings::self()->smbspoolItem()->setDefaultValue( program_paths["smbspool"] ); if ( Smb4KSettings::smbspool().isEmpty() ) { Smb4KSettings::self()->smbspoolItem()->setDefault(); } } if ( !program_list["net"] ) { missing.append( "net" ); } else { Smb4KSettings::self()->netItem()->setDefaultValue( program_paths["net"] ); if ( Smb4KSettings::net().isEmpty() ) { Smb4KSettings::self()->netItem()->setDefault(); } } #ifndef __FreeBSD__ if ( !program_list["mount.cifs"] && !program_list["smbmount"] ) { missing.append( "mount.cifs & smbmount" ); } else { // One of the two programs is at least present, so we can do // it like this: TQString filesystem; if ( program_list["mount.cifs"] ) { Smb4KSettings::self()->mount_cifsItem()->setDefaultValue( program_paths["mount.cifs"] ); if ( Smb4KSettings::mount_cifs().isEmpty() ) { Smb4KSettings::self()->mount_cifsItem()->setDefault(); } } else { Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::SMBFS ); } if ( program_list["smbmount"] ) { Smb4KSettings::self()->smbmountItem()->setDefaultValue( program_paths["smbmount"] ); if ( Smb4KSettings::smbmount().isEmpty() ) { Smb4KSettings::self()->smbmountItem()->setDefault(); } } else { Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::CIFS ); } } if ( !program_list["umount.cifs"] && !program_list["smbumount"] ) { missing.append( "umount.cifs & smbumount" ); } else { // One of the two programs is at least present, so we can do // it like this: TQString filesystem; if ( program_list["umount.cifs"] ) { Smb4KSettings::self()->umount_cifsItem()->setDefaultValue( program_paths["umount.cifs"] ); if ( Smb4KSettings::umount_cifs().isEmpty() ) { Smb4KSettings::self()->umount_cifsItem()->setDefault(); } } else { Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::SMBFS ); } if ( program_list["smbumount"] ) { Smb4KSettings::self()->smbumountItem()->setDefaultValue( program_paths["smbumount"] ); if ( Smb4KSettings::smbumount().isEmpty() ) { Smb4KSettings::self()->smbumountItem()->setDefault(); } } else { Smb4KSettings::setFilesystem( Smb4KSettings::EnumFilesystem::CIFS ); } } if ( !program_list["mount"] ) { missing.append( "mount" ); } else { Smb4KSettings::self()->mountItem()->setDefaultValue( program_paths["mount"] ); if ( Smb4KSettings::mount().isEmpty() ) { Smb4KSettings::self()->mountItem()->setDefault(); } } #else if ( !program_list["mount_smbfs"] ) { missing.append( "mount_smbfs" ); } else { Smb4KSettings::self()->mount_smbfsItem()->setDefaultValue( program_paths["mount_smbfs"] ); if ( Smb4KSettings::mount_smbfs().isEmpty() ) { Smb4KSettings::self()->mount_smbfsItem()->setDefault(); } } if ( !program_list["smbutil"] ) { missing.append( "smbutil" ); } else { Smb4KSettings::self()->smbutilItem()->setDefaultValue( program_paths["smbutil"] ); if ( Smb4KSettings::smbutil().isEmpty() ) { Smb4KSettings::self()->smbutilItem()->setDefault(); } } #endif if ( !program_list["umount"] ) { missing.append( "umount" ); } else { Smb4KSettings::self()->umountItem()->setDefaultValue( program_paths["umount"] ); if ( Smb4KSettings::umount().isEmpty() ) { Smb4KSettings::self()->umountItem()->setDefault(); } } if ( !program_list["smb4k_mount"] ) { missing.append( "smb4k_mount" ); } else { Smb4KSettings::self()->smb4k_mountItem()->setDefaultValue( program_paths["smb4k_mount"] ); if ( Smb4KSettings::smb4k_mount().isEmpty() ) { Smb4KSettings::self()->smb4k_mountItem()->setDefault(); } } if ( !program_list["smb4k_umount"] ) { missing.append( "smb4k_umount" ); } else { Smb4KSettings::self()->smb4k_umountItem()->setDefaultValue( program_paths["smb4k_umount"] ); if ( Smb4KSettings::smb4k_umount().isEmpty() ) { Smb4KSettings::self()->smb4k_umountItem()->setDefault(); } } if ( !program_list["smb4k_kill"] ) { missing.append( "smb4k_kill" ); } else { Smb4KSettings::self()->smb4k_killItem()->setDefaultValue( program_paths["smb4k_kill"] ); if ( Smb4KSettings::smb4k_kill().isEmpty() ) { Smb4KSettings::self()->smb4k_killItem()->setDefault(); } } if ( !program_list["smb4k_cat"] ) { missing.append( "smb4k_cat" ); } else { Smb4KSettings::self()->smb4k_catItem()->setDefaultValue( program_paths["smb4k_cat"] ); if ( Smb4KSettings::smb4k_cat().isEmpty() ) { Smb4KSettings::self()->smb4k_catItem()->setDefault(); } } if ( !program_list["smb4k_mv"] ) { missing.append( "smb4k_mv" ); } else { Smb4KSettings::self()->smb4k_mvItem()->setDefaultValue( program_paths["smb4k_mv"] ); if ( Smb4KSettings::smb4k_mv().isEmpty() ) { Smb4KSettings::self()->smb4k_mvItem()->setDefault(); } } if ( !missing.isEmpty() ) { // Error out if one of the mandatory programs is // missing: Smb4KError::error( ERROR_MISSING_PROGRAMS, missing.join( ", " ) ); exit( EXIT_FAILURE ); } else { // Check for the optional programs: if ( !program_list["super"] ) { if ( (Smb4KSettings::useForceUnmount() || Smb4KSettings::alwaysUseSuperUser()) && Smb4KSettings::superUserProgram() == Smb4KSettings::EnumSuperUserProgram::Super ) { Smb4KError::information( INFO_DISABLE_SUID_FEATURE, "super" ); // Reset the super user settings: Smb4KSettings::self()->useForceUnmountItem()->setDefault(); Smb4KSettings::self()->alwaysUseSuperUserItem()->setDefault(); } else { // Do nothing } } else { Smb4KSettings::self()->superItem()->setDefaultValue( program_paths["super"] ); if ( Smb4KSettings::super().isEmpty() ) { Smb4KSettings::self()->superItem()->setDefault(); } } if ( !program_list["sudo"] ) { if ( (Smb4KSettings::useForceUnmount() || Smb4KSettings::alwaysUseSuperUser()) && Smb4KSettings::superUserProgram() == Smb4KSettings::EnumSuperUserProgram::Super ) { Smb4KError::information( INFO_DISABLE_SUID_FEATURE, "sudo" ); // Reset the super user settings: Smb4KSettings::self()->useForceUnmountItem()->setDefault(); Smb4KSettings::self()->alwaysUseSuperUserItem()->setDefault(); } else { // Do nothing } } else { Smb4KSettings::self()->sudoItem()->setDefaultValue( program_paths["sudo"] ); if ( Smb4KSettings::sudo().isEmpty() ) { Smb4KSettings::self()->sudoItem()->setDefault(); } } if ( program_list["dvips"] ) { Smb4KSettings::self()->dvipsItem()->setDefaultValue( program_paths["dvips"] ); if ( Smb4KSettings::dvips().isEmpty() ) { Smb4KSettings::self()->dvipsItem()->setDefault(); } } if ( program_list["enscript"] ) { Smb4KSettings::self()->enscriptItem()->setDefaultValue( program_paths["enscript"] ); if ( Smb4KSettings::enscript().isEmpty() ) { Smb4KSettings::self()->enscriptItem()->setDefault(); } } if ( program_list["rsync"] ) { Smb4KSettings::self()->rsyncItem()->setDefaultValue( program_paths["rsync"] ); if ( Smb4KSettings::rsync().isEmpty() ) { Smb4KSettings::self()->rsyncItem()->setDefault(); } } if ( program_list["konsole"] ) { Smb4KSettings::self()->konsoleItem()->setDefaultValue( program_paths["konsole"] ); if ( Smb4KSettings::konsole().isEmpty() ) { Smb4KSettings::self()->konsoleItem()->setDefault(); } } // Write the configuration to disk: Smb4KSettings::writeConfig(); } } void Smb4KCore::setDefaultSettings() { // Samba options that have to be dynamically imported from smb.conf: TQMap opts = optionsHandler()->globalSambaOptions(); if ( !opts["netbios name"].isEmpty() ) { Smb4KSettings::self()->netBIOSNameItem()->setDefaultValue( opts["netbios name"] ); if ( Smb4KSettings::netBIOSName().isEmpty() ) { Smb4KSettings::self()->netBIOSNameItem()->setDefault(); } } if ( !opts["workgroup"].isEmpty() ) { Smb4KSettings::self()->domainNameItem()->setDefaultValue( opts["workgroup"] ); if ( Smb4KSettings::domainName().isEmpty() ) { Smb4KSettings::self()->domainNameItem()->setDefault(); } } if ( !opts["socket options"].isEmpty() ) { Smb4KSettings::self()->socketOptionsItem()->setDefaultValue( opts["socket options"] ); if ( Smb4KSettings::socketOptions().isEmpty() ) { Smb4KSettings::self()->socketOptionsItem()->setDefault(); } } if ( !opts["netbios scope"].isEmpty() ) { Smb4KSettings::self()->netBIOSScopeItem()->setDefaultValue( opts["netbios scope"] ); if ( Smb4KSettings::netBIOSScope().isEmpty() ) { Smb4KSettings::self()->netBIOSScopeItem()->setDefault(); } } if ( !opts["name resolve order"].isEmpty() ) { Smb4KSettings::self()->nameResolveOrderItem()->setDefaultValue( opts["name resolve order"] ); if ( Smb4KSettings::nameResolveOrder().isEmpty() ) { Smb4KSettings::self()->nameResolveOrderItem()->setDefault(); } } if ( !opts["interfaces"].isEmpty() ) { Smb4KSettings::self()->broadcastAddressItem()->setDefaultValue( opts["interfaces"] ); if ( Smb4KSettings::broadcastAddress().isEmpty() ) { Smb4KSettings::self()->broadcastAddressItem()->setDefault(); } } } ///////////////////////////////////////////////////////////////////////////// // TQT_SLOT IMPLEMENTATIONS ///////////////////////////////////////////////////////////////////////////// void Smb4KCore::slotSetScannerState( int state ) { m_scanner_state = state; setCurrentState( state ); emit runStateChanged(); } void Smb4KCore::slotSetMounterState( int state ) { m_mounter_state = state; setCurrentState( state ); emit runStateChanged(); } void Smb4KCore::slotSetPrinterHandlerState( int state ) { m_print_state = state; setCurrentState( state ); emit runStateChanged(); } void Smb4KCore::slotSetSynchronizerState( int state ) { m_syncer_state = state; setCurrentState( state ); emit runStateChanged(); } void Smb4KCore::slotSetPreviewerState( int state ) { m_previewer_state = state; setCurrentState( state ); emit runStateChanged(); } void Smb4KCore::slotShutdown() { Smb4KSettings::writeConfig(); } #include "smb4kcore.moc"