You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1721 lines
48 KiB
1721 lines
48 KiB
/***************************************************************************
|
|
smb4kscanner.cpp - The network scan core class of Smb4K.
|
|
-------------------
|
|
begin : Sam Mai 31 2003
|
|
copyright : (C) 2003-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 <tqapplication.h>
|
|
#include <tqmap.h>
|
|
#include <tqdeepcopy.h>
|
|
|
|
// KDE includes
|
|
#include <klocale.h>
|
|
#include <kapplication.h>
|
|
#include <kdebug.h>
|
|
#include <ksocketaddress.h>
|
|
|
|
// system includes
|
|
#include <stdlib.h>
|
|
|
|
// Application specific includes.
|
|
#include "smb4kscanner.h"
|
|
#include "smb4kscanner_p.h"
|
|
#include "smb4kauthinfo.h"
|
|
#include "smb4kerror.h"
|
|
#include "smb4kglobal.h"
|
|
#include "smb4ksambaoptionshandler.h"
|
|
#include "smb4kpasswordhandler.h"
|
|
#include "smb4knetworkitems.h"
|
|
#include "smb4ksettings.h"
|
|
|
|
using namespace Smb4KGlobal;
|
|
|
|
static bool created_workgroups_list = false;
|
|
static bool created_hosts_list = false;
|
|
|
|
|
|
|
|
Smb4KScanner::Smb4KScanner( TQValueList<Smb4KWorkgroupItem *> *workgroups, TQValueList<Smb4KHostItem *> *hosts,
|
|
TQObject *tqparent, const char *name )
|
|
: TQObject( tqparent, name ), m_workgroups_list( workgroups ), m_hosts_list( hosts )
|
|
{
|
|
m_priv = new Smb4KScannerPrivate;
|
|
|
|
if ( !m_workgroups_list )
|
|
{
|
|
created_workgroups_list = true;
|
|
m_workgroups_list = new TQValueList<Smb4KWorkgroupItem *>;
|
|
}
|
|
else
|
|
{
|
|
// The list was passed to the constructor from outside.
|
|
}
|
|
|
|
if ( !m_hosts_list )
|
|
{
|
|
created_hosts_list = true;
|
|
m_hosts_list = new TQValueList<Smb4KHostItem *>;
|
|
}
|
|
else
|
|
{
|
|
// The list was passed to the constructor from outside.
|
|
}
|
|
|
|
m_proc = new KProcess( this, "ScannerMainProcess" );
|
|
m_proc->setUseShell( true );
|
|
|
|
m_working = false;
|
|
|
|
m_queue.setAutoDelete( true );
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStdout( KProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStdout( KProcess *, char *, int ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( processExited( KProcess* ) ),
|
|
this, TQT_SLOT( slotProcessExited( KProcess * ) ) );
|
|
|
|
connect( m_proc, TQT_SIGNAL( receivedStderr( KProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedStderr( KProcess *, char *, int ) ) );
|
|
}
|
|
|
|
|
|
Smb4KScanner::~Smb4KScanner()
|
|
{
|
|
abort();
|
|
|
|
// Delete the list of workgroups, if necessary:
|
|
if ( created_workgroups_list )
|
|
{
|
|
for ( TQValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
m_workgroups_list->clear();
|
|
|
|
delete m_workgroups_list;
|
|
}
|
|
else
|
|
{
|
|
// The list of workgroups is handled outside of this class.
|
|
}
|
|
|
|
// Delete the list of hosts, if necessary:
|
|
if ( created_hosts_list )
|
|
{
|
|
for ( TQValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
m_hosts_list->clear();
|
|
|
|
delete m_hosts_list;
|
|
}
|
|
else
|
|
{
|
|
// The list of hosts is handled outside of this class.
|
|
}
|
|
|
|
delete m_priv;
|
|
}
|
|
|
|
|
|
void Smb4KScanner::init()
|
|
{
|
|
m_timer_id = startTimer( TIMER_INTERVAL );
|
|
rescan();
|
|
}
|
|
|
|
|
|
void Smb4KScanner::rescan()
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:" ).tqarg( Init ) ) );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Scans for workgroup members. (public part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::getWorkgroupMembers( const TQString &workgroup, const TQString &master, const TQString &ip )
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4" ).tqarg( Hosts ).tqarg( workgroup, master, ip ) ) );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Scans for shares on a selected host. (public part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::getShares( const TQString &workgroup, const TQString &host, const TQString &ip, const TQString &protocol )
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4:%5" ).tqarg( Shares ).tqarg( workgroup, host, ip ).tqarg( protocol ) ) );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Gets more info on a selected host. (public part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::getInfo( const TQString &workgroup, const TQString &host, const TQString &ip )
|
|
{
|
|
Smb4KHostItem *item = getHost( host, workgroup );
|
|
|
|
if ( item && item->infoChecked() )
|
|
{
|
|
emit info( item );
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// Avoid several queueing up:
|
|
item->setInfoChecked( true );
|
|
}
|
|
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4" ).tqarg( Info ).tqarg( workgroup, host, ip ) ) );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Searches for a host. (public part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::search( const TQString &host )
|
|
{
|
|
// Check whether we already have this host in
|
|
// the list:
|
|
Smb4KHostItem *item = getHost( host );
|
|
|
|
if ( item )
|
|
{
|
|
emit searchResult( item );
|
|
|
|
return;
|
|
}
|
|
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2" ).tqarg( Search ).tqarg( host ) ) );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Aborts any process that is running.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::abort()
|
|
{
|
|
m_queue.clear();
|
|
|
|
if ( m_proc->isRunning() )
|
|
{
|
|
m_proc->kill();
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
This function retrieves the initial browse list
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::scanNetwork()
|
|
{
|
|
abort();
|
|
|
|
TQString command;
|
|
|
|
// Look up the workgroups/domains and their master browsers.
|
|
// At the moment we have three methods:
|
|
// (1) Smb4KSettings::EnumBrowseList::LookupDomains: This method is
|
|
// the most reliable one. It uses nmblookup and will only find
|
|
// *active* workgroup master browsers and thus active domains.
|
|
// (2) Smb4KSettings::EnumBrowseList::QueryCurrentMaster: This
|
|
// method will query the current master browser of the local
|
|
// workgroup/domain. This method is not as reliable as the first
|
|
// one, because you might get wrong (i. e. outdated) master
|
|
// browsers for the workgroups or even empty workgroups.
|
|
// (3) Smb4KSettings::EnumBrowseList::QueryCustomMaster: This method
|
|
// is similar to the second one, but the user has defined a fixed
|
|
// host name or IP address.
|
|
// (4) Smb4KSettings::EnumBrowseList::ScanBroadcastAreas: Scan the
|
|
// user given broadcast addresses for active hosts (IP scan)
|
|
|
|
switch ( Smb4KSettings::browseList() )
|
|
{
|
|
case Smb4KSettings::EnumBrowseList::LookupDomains:
|
|
{
|
|
command.append( "nmblookup -M " );
|
|
command.append( optionsHandler()->nmblookupOptions() );
|
|
command.append( " -- - | grep '<01>' | awk '{print $1}'" );
|
|
command.append( !optionsHandler()->winsServer().isEmpty() ?
|
|
TQString( " | xargs nmblookup -R -U %1 -A " ).tqarg( optionsHandler()->winsServer() ) :
|
|
" | xargs nmblookup -A " );
|
|
command.append( optionsHandler()->nmblookupOptions() );
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( Workgroups );
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumBrowseList::QueryCurrentMaster:
|
|
{
|
|
command.append( "net " );
|
|
command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupMaster,
|
|
Smb4KSettings::domainName() ) );
|
|
command.append( " -U % | xargs net " );
|
|
command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Domain,
|
|
TQString() ) );
|
|
command.append( " -U % -S" );
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( QueryHost );
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumBrowseList::QueryCustomMaster:
|
|
{
|
|
command.append( "net " );
|
|
command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupHost,
|
|
Smb4KSettings::customMasterBrowser() ) );
|
|
command.append( " -U % -S "+KProcess::quote( Smb4KSettings::customMasterBrowser() ) );
|
|
command.append( " | xargs net " );
|
|
command.append( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Domain,
|
|
TQString() ) );
|
|
command.append( " -U % -S "+KProcess::quote( Smb4KSettings::customMasterBrowser() )+" -I " );
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( QueryHost );
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumBrowseList::ScanBroadcastAreas:
|
|
{
|
|
// Get the broadcast addresses that are to be scanned:
|
|
TQStringList addresses = TQStringList::split( ",", Smb4KSettings::broadcastAreas(), false );
|
|
|
|
// Build the command:
|
|
for ( TQStringList::ConstIterator it = addresses.begin(); it != addresses.end(); ++it )
|
|
{
|
|
if ( !(*it).isEmpty() )
|
|
{
|
|
command.append( "nmblookup " );
|
|
// We want all globally defined options for nmblookup, except
|
|
// the broadcast address, because that is needed for the IP
|
|
// scan:
|
|
command.append( optionsHandler()->nmblookupOptions( false ) );
|
|
command.append( " -B "+*it+" -- '*' " );
|
|
command.append( "| sed -e /querying/d | awk '{print $1}' " );
|
|
command.append( "| xargs nmblookup " );
|
|
// This time we want to have the globally defined broadcast
|
|
// address:
|
|
command.append( optionsHandler()->nmblookupOptions() );
|
|
// Include the WINS server:
|
|
command.append( !optionsHandler()->winsServer().isEmpty() ?
|
|
" -R -U "+optionsHandler()->winsServer()+" " : "" );
|
|
command.append( " -A" );
|
|
command.append( " ; " );
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Get rid of the last 3 characters (" ; "):
|
|
command.truncate( command.length() - 3 );
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( IPScan );
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Scans for workgroup members. (private part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::scanForWorkgroupMembers( const TQString &workgroup, const TQString &master, const TQString &ip )
|
|
{
|
|
m_priv->setWorkgroup( workgroup );
|
|
m_priv->setHost( master );
|
|
m_priv->setIP( ip );
|
|
|
|
TQString command;
|
|
|
|
if ( !ip.isEmpty() )
|
|
{
|
|
command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::ServerDomain, TQString() ) );
|
|
command.append( " -I "+ip );
|
|
command.append( " -w "+KProcess::quote( workgroup ) );
|
|
command.append( " -S "+KProcess::quote( master ) );
|
|
|
|
Smb4KAuthInfo authInfo( workgroup, master, TQString() );
|
|
(void) passwordHandler()->readAuth( &authInfo );
|
|
|
|
if ( !authInfo.user().isEmpty() )
|
|
{
|
|
command.append( TQString( " -U %1" ).tqarg( KProcess::quote( authInfo.user() ) ) );
|
|
|
|
if ( !authInfo.password().isEmpty() )
|
|
{
|
|
m_proc->setEnvironment( "PASSWD", authInfo.password() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command.append( " -U %" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::LookupHost, KProcess::quote( master ) ) );
|
|
command.append( " -S "+KProcess::quote( master )+" -w "+KProcess::quote( workgroup )+" -U % " );
|
|
// FIXME: Maybe we need to know the shell if the user does not use a
|
|
// sh-compatible one...?
|
|
command.append( "| xargs -IIPADDR " );
|
|
command.append( getenv( "SHELL" ) );
|
|
command.append( " -c 'echo \"*** "+master+": IPADDR ***\" && " );
|
|
command.append( "net "+optionsHandler()->netOptions( Smb4KSambaOptionsHandler::ServerDomain, TQString() ) );
|
|
command.append( " -I IPADDR" );
|
|
command.append( " -w "+KProcess::quote( workgroup ) );
|
|
command.append( " -S "+KProcess::quote( master ) );
|
|
|
|
Smb4KAuthInfo authInfo( workgroup, master, TQString() );
|
|
(void) passwordHandler()->readAuth( &authInfo );
|
|
|
|
if ( !authInfo.user().isEmpty() )
|
|
{
|
|
command.append( TQString( " -U %1'" ).tqarg( KProcess::quote( authInfo.user() ) ) );
|
|
|
|
if ( !authInfo.password().isEmpty() )
|
|
{
|
|
m_proc->setEnvironment( "PASSWD", authInfo.password() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command.append( " -U %'" );
|
|
}
|
|
}
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( Hosts );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Scans for shares on a selected host. (private part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::scanForShares( const TQString &workgroup, const TQString &host, const TQString &ip, const TQString &protocol )
|
|
{
|
|
m_priv->setWorkgroup( workgroup );
|
|
m_priv->setHost( host );
|
|
m_priv->setIP( ip );
|
|
|
|
Smb4KAuthInfo *auth = passwordHandler()->readAuth( new Smb4KAuthInfo( workgroup, host, TQString() ) );
|
|
|
|
TQString command;
|
|
|
|
command = TQString( "net %1 -w %2 -S %3" ).tqarg( optionsHandler()->netOptions( Smb4KSambaOptionsHandler::Share, host, protocol ) ).tqarg( KProcess::quote( workgroup ), KProcess::quote( host ) );
|
|
|
|
if ( !ip.isEmpty() )
|
|
{
|
|
command.append( TQString( " -I %1" ).tqarg( KProcess::quote( ip ) ) );
|
|
}
|
|
|
|
if ( !auth->user().isEmpty() )
|
|
{
|
|
command.append( TQString( " -U %1" ).tqarg( KProcess::quote( auth->user() ) ) );
|
|
|
|
if ( !auth->password().isEmpty() )
|
|
{
|
|
m_proc->setEnvironment( "PASSWD", auth->password() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
command.append( " -U guest%" );
|
|
}
|
|
|
|
delete auth;
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( Shares );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Gets more info on a selected host. (private part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::scanForInfo( const TQString &workgroup, const TQString &host, const TQString &ip )
|
|
{
|
|
m_priv->setWorkgroup( workgroup );
|
|
m_priv->setHost( host );
|
|
m_priv->setIP( ip );
|
|
|
|
TQString smbclient_options = optionsHandler()->smbclientOptions();
|
|
|
|
TQString command = TQString( "smbclient -d1 -U guest% -W %1 -L %2" ).tqarg( KProcess::quote( workgroup ) ).tqarg( KProcess::quote( host ) );
|
|
|
|
if ( !ip.isEmpty() )
|
|
{
|
|
command.append( TQString( " -I %1" ).tqarg( KProcess::quote( ip ) ) );
|
|
}
|
|
|
|
if ( !smbclient_options.stripWhiteSpace().isEmpty() )
|
|
{
|
|
command.append( smbclient_options );
|
|
}
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( Info );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Searches for a host. (private part)
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::searchForHost( const TQString &host )
|
|
{
|
|
// We need this because smbclient won't return the host name.
|
|
KNetwork::KIpAddress ip_address = KNetwork::KIpAddress( host );
|
|
|
|
if ( Smb4KSettings::searchMethod() == Smb4KSettings::EnumSearchMethod::Smbclient &&
|
|
(ip_address.isIPv4Addr() || ip_address.isIPv6Addr()) )
|
|
{
|
|
Smb4KError::error( ERROR_IP_CANNOT_BE_USED );
|
|
m_working = false;
|
|
emit state( SCANNER_STOP );
|
|
return;
|
|
}
|
|
|
|
m_priv->setHost( host );
|
|
|
|
TQString wins = optionsHandler()->winsServer();
|
|
TQString nmblookup_options = optionsHandler()->nmblookupOptions();
|
|
TQString smbclient_options = optionsHandler()->smbclientOptions();
|
|
|
|
TQString command;
|
|
|
|
switch ( Smb4KSettings::searchMethod() )
|
|
{
|
|
case Smb4KSettings::EnumSearchMethod::Nmblookup:
|
|
{
|
|
command = TQString( "nmblookup" );
|
|
|
|
if ( !nmblookup_options.stripWhiteSpace().isEmpty() )
|
|
{
|
|
command.append( nmblookup_options );
|
|
}
|
|
|
|
if ( host.contains( '.', true ) != 3 )
|
|
{
|
|
if ( !wins.isEmpty() )
|
|
{
|
|
command.append( TQString( " -R -U %1 %2 -S | grep '<00>' | sed -e 's/<00>.*//'" ).tqarg( wins ).tqarg( m_priv->host() ) );
|
|
}
|
|
else
|
|
{
|
|
command.append( TQString( " %1 -S | grep '<00>' | sed -e 's/<00>.*//'" ).tqarg( m_priv->host() ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !wins.isEmpty() )
|
|
{
|
|
command.append( TQString( " -R -U %1 %2 -A | grep '<00>' | sed -e 's/<00>.*//'" ).tqarg( wins ).tqarg( m_priv->host() ) );
|
|
}
|
|
else
|
|
{
|
|
command.append( TQString( " %1 -A | grep '<00>' | sed -e 's/<00>.*//'" ).tqarg( m_priv->host() ) );
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumSearchMethod::Smbclient:
|
|
{
|
|
command = TQString( "smbclient -d2 -U % -L %1" ).tqarg( m_priv->host() );
|
|
|
|
if ( !smbclient_options.stripWhiteSpace().isEmpty() )
|
|
{
|
|
command.append( smbclient_options );
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
// Something went wrong. Stop here.
|
|
return;
|
|
}
|
|
}
|
|
|
|
*m_proc << command;
|
|
|
|
startProcess( Search );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Starts the process of the scanner.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::startProcess( int state )
|
|
{
|
|
m_state = state;
|
|
m_buffer = TQString();
|
|
|
|
if ( state != Info )
|
|
{
|
|
TQApplication::setOverrideCursor( waitCursor );
|
|
}
|
|
|
|
m_proc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
End the process and tell, what to do with the data.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::endProcess()
|
|
{
|
|
switch ( m_state )
|
|
{
|
|
case Workgroups:
|
|
case QueryHost:
|
|
processWorkgroups();
|
|
break;
|
|
case IPScan:
|
|
processIPScan();
|
|
break;
|
|
case Hosts:
|
|
processWorkgroupMembers();
|
|
break;
|
|
case Shares:
|
|
processShares();
|
|
break;
|
|
case Info:
|
|
processInfo();
|
|
break;
|
|
case Search:
|
|
processSearch();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
m_state = Idle;
|
|
|
|
m_priv->clearData();
|
|
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
m_proc->clearArguments();
|
|
|
|
m_working = false;
|
|
|
|
emit state( SCANNER_STOP );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the list of workgroups.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processWorkgroups()
|
|
{
|
|
TQStringList list = TQStringList::split( '\n', m_buffer, false );
|
|
|
|
for ( TQValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
for ( TQValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
m_workgroups_list->clear();
|
|
m_hosts_list->clear();
|
|
|
|
if ( m_state == Workgroups )
|
|
{
|
|
TQString workgroup, master, ip;
|
|
|
|
for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).stripWhiteSpace().startsWith( "Looking" ) )
|
|
{
|
|
ip = (*it).section( "of", 1, 1 ).stripWhiteSpace();
|
|
|
|
continue;
|
|
}
|
|
else if ( (*it).contains( "<00>" ) != 0 && (*it).contains( "<GROUP>" ) == 0 )
|
|
{
|
|
if ( workgroup.isEmpty() && master.isEmpty() && !ip.isEmpty() )
|
|
{
|
|
master = (*it).section( "<00>", 0, 0 ).stripWhiteSpace();
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if ( (*it).contains( "<00>" ) != 0 && (*it).contains( "<GROUP>" ) != 0 )
|
|
{
|
|
if ( workgroup.isEmpty() && !master.isEmpty() && !ip.isEmpty() )
|
|
{
|
|
workgroup = (*it).left( (*it).find( "<00>" ) ).stripWhiteSpace();
|
|
|
|
m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, master, ip ) );
|
|
|
|
Smb4KHostItem *master_item = new Smb4KHostItem( workgroup, master, TQString(), ip );
|
|
master_item->setMaster( true );
|
|
|
|
m_hosts_list->append( master_item );
|
|
|
|
workgroup = TQString();
|
|
master = TQString();
|
|
ip = TQString();
|
|
}
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else if ( m_state == QueryHost )
|
|
{
|
|
bool process = false;
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
TQString line = (*it).stripWhiteSpace();
|
|
|
|
if ( line.startsWith( "-------------" ) )
|
|
{
|
|
process = true;
|
|
|
|
continue;
|
|
}
|
|
|
|
if ( process && !line.isEmpty() )
|
|
{
|
|
TQString workgroup = line.section( " ", 0, 0 ).stripWhiteSpace();
|
|
TQString master = line.section( " ", 1, -1 ).stripWhiteSpace();
|
|
|
|
m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, master, TQString() ) );
|
|
|
|
Smb4KHostItem *master_item = new Smb4KHostItem( workgroup, master );
|
|
master_item->setMaster( true );
|
|
|
|
m_hosts_list->append( master_item );
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
lookupIPAddresses();
|
|
|
|
emit workgroups( *m_workgroups_list );
|
|
emit hostListChanged();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the data from the IP range scan
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processIPScan()
|
|
{
|
|
TQStringList list = TQStringList::split( '\n', m_buffer, true );
|
|
|
|
for ( TQValueList<Smb4KWorkgroupItem *>::Iterator it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
for ( TQValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
delete *it;
|
|
}
|
|
|
|
m_workgroups_list->clear();
|
|
m_hosts_list->clear();
|
|
|
|
// Process the data:
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).startsWith( "Looking up status of" ) )
|
|
{
|
|
TQString workgroup, host, ip;
|
|
bool master = false;
|
|
|
|
// Get the IP address of this host.
|
|
ip = (*it).section( "of", 1, 1 ).stripWhiteSpace();
|
|
|
|
// Loop through the data:
|
|
for ( TQStringList::ConstIterator i = it; i != list.end(); ++i )
|
|
{
|
|
if ( (*i).contains( " <00> " ) != 0 )
|
|
{
|
|
if ( (*i).contains( " <GROUP> " ) != 0 )
|
|
{
|
|
workgroup = (*i).section( "<00>", 0, 0 ).stripWhiteSpace();
|
|
}
|
|
else
|
|
{
|
|
host = (*i).section( "<00>", 0, 0 ).stripWhiteSpace();
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if ( (*i).contains( "__MSBROWSE__" ) != 0 && (*i).contains( " <01> " ) != 0 )
|
|
{
|
|
master = true;
|
|
|
|
continue;
|
|
}
|
|
else if ( (*i).contains( "MAC Address" ) != 0 || (*i).stripWhiteSpace().isEmpty() )
|
|
{
|
|
it = i;
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( !workgroup.isEmpty() )
|
|
{
|
|
Smb4KWorkgroupItem *workgroup_item = getWorkgroup( workgroup );
|
|
|
|
if ( workgroup_item )
|
|
{
|
|
if ( master )
|
|
{
|
|
workgroup_item->setMaster( host, ip );
|
|
}
|
|
else
|
|
{
|
|
// Do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( master )
|
|
{
|
|
m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, host, ip ) );
|
|
}
|
|
else
|
|
{
|
|
m_workgroups_list->append( new Smb4KWorkgroupItem( workgroup, TQString(), TQString() ) );
|
|
}
|
|
}
|
|
|
|
Smb4KHostItem *host_item = new Smb4KHostItem( workgroup, host, TQString(), ip );
|
|
host_item->setMaster( master );
|
|
|
|
m_hosts_list->append( host_item );
|
|
}
|
|
else
|
|
{
|
|
// Do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// No extra lookup of IP addresses is needed since
|
|
// we searched for IP addresses. :)
|
|
|
|
emit workgroups( *m_workgroups_list );
|
|
emit members( m_priv->workgroup(), *m_hosts_list );
|
|
emit hostListChanged();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the member list of a workgroup.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processWorkgroupMembers()
|
|
{
|
|
TQStringList list = TQStringList::split( '\n', m_buffer, false );
|
|
|
|
switch ( Smb4KSettings::browseList() )
|
|
{
|
|
case Smb4KSettings::EnumBrowseList::LookupDomains:
|
|
case Smb4KSettings::EnumBrowseList::QueryCurrentMaster:
|
|
case Smb4KSettings::EnumBrowseList::QueryCustomMaster:
|
|
{
|
|
if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 ||
|
|
m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 ||
|
|
m_buffer.contains( "The username or password was not correct" ) != 0 )
|
|
{
|
|
// Authentication failed:
|
|
emit failed();
|
|
|
|
if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(),
|
|
TQString(), Smb4KPasswordHandler::AccessDenied,
|
|
kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4" ).tqarg( Hosts ).tqarg( m_priv->workgroup(), m_priv->host(), m_priv->ip() ) ) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
else if ( m_buffer.contains( "Could not connect to server" ) != 0 ||
|
|
m_buffer.contains( "Unable to find a suitable server" ) != 0 ||
|
|
m_buffer.contains( "Invalid ip address specified" ) != 0 )
|
|
{
|
|
// If the IP address is empty, the shell output contains
|
|
// the IP address. Remove it, because it will confuse
|
|
// the user:
|
|
if ( m_priv->ip().isEmpty() )
|
|
{
|
|
list.remove( list.first() );
|
|
}
|
|
|
|
// Notify the rest of the program, that something went wrong.
|
|
emit failed();
|
|
|
|
// Notify the user:
|
|
Smb4KError::error( ERROR_GETTING_MEMBERS, TQString(), list.join( "\n" ) );
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// Do nothing
|
|
}
|
|
|
|
TQValueList<Smb4KHostItem *> hosts;
|
|
|
|
bool process = false;
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
TQString line = (*it).stripWhiteSpace();
|
|
|
|
if ( !process )
|
|
{
|
|
// Find the IP address in case we did not know it at the beginning
|
|
// of the scan process and put it into m_priv.ip():
|
|
if ( m_priv->ip().isEmpty() && line.startsWith( "***" ) && line.endsWith( "***" ) )
|
|
{
|
|
m_priv->setIP( line.section( ":", 1, 1 ).section( "***", 0, 0 ).stripWhiteSpace() );
|
|
|
|
continue;
|
|
}
|
|
|
|
// Find the line after that we will have to process the output
|
|
// to get the servers belonging to this workgroup:
|
|
if ( line.startsWith( "-------------" ) )
|
|
{
|
|
process = true;
|
|
|
|
continue;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if ( !line.isEmpty() )
|
|
{
|
|
TQString host, comment;
|
|
|
|
if ( line.contains( " " ) == 0 )
|
|
{
|
|
host = line;
|
|
}
|
|
else
|
|
{
|
|
host = line.section( " ", 0, 0 ).stripWhiteSpace();
|
|
comment = line.section( " ", 1, -1 ).stripWhiteSpace();
|
|
}
|
|
|
|
Smb4KHostItem *item = new Smb4KHostItem( m_priv->workgroup(), host, comment );
|
|
|
|
if ( TQString::compare( item->name(), m_priv->host() ) == 0 )
|
|
{
|
|
// The item is identical to the master browser! Give the
|
|
// respective workgroup item the IP address of the master
|
|
// if it is not already present.
|
|
Smb4KWorkgroupItem *workgroupItem = getWorkgroup( m_priv->workgroup() );
|
|
|
|
if ( workgroupItem && workgroupItem->masterIP().isEmpty() )
|
|
{
|
|
workgroupItem->setMasterIP( m_priv->ip() );
|
|
}
|
|
|
|
// Set the IP address for new item (we only know it at this point,
|
|
// because this is the workgroup master):
|
|
item->setIPAddress( m_priv->ip() );
|
|
// Set it to be the master:
|
|
item->setMaster( true );
|
|
}
|
|
|
|
hosts.append( item );
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If the list is empty, put the master in.
|
|
if ( hosts.isEmpty() )
|
|
{
|
|
Smb4KHostItem *item = new Smb4KHostItem( m_priv->workgroup(), m_priv->host() );
|
|
item->setMaster( true );
|
|
|
|
hosts.append( item );
|
|
}
|
|
|
|
emit members( m_priv->workgroup(), hosts );
|
|
|
|
// Now put the hosts in m_hosts_list:
|
|
for ( TQValueList<Smb4KHostItem *>::Iterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
if ( TQString::compare( (*it)->workgroup(), m_priv->workgroup() ) == 0 )
|
|
{
|
|
bool found = false;
|
|
|
|
for ( TQValueList<Smb4KHostItem *>::Iterator i = hosts.begin(); i != hosts.end(); ++i )
|
|
{
|
|
if ( *i && TQString::compare( (*i)->name(), (*it)->name() ) == 0 )
|
|
{
|
|
found = true;
|
|
|
|
// The only thing that might be missing is the comment.
|
|
(*it)->setComment( (*i)->comment() );
|
|
|
|
delete *i;
|
|
*i = NULL;
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( !found )
|
|
{
|
|
delete *it;
|
|
*it = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
m_hosts_list->remove( NULL );
|
|
hosts.remove( NULL );
|
|
|
|
// Append the list:
|
|
*m_hosts_list += hosts;
|
|
|
|
// Lookup IP addresses.
|
|
lookupIPAddresses();
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumBrowseList::ScanBroadcastAreas:
|
|
{
|
|
if ( m_buffer.contains( "NT_STATUS_ACCESS_DENIED" ) != 0 ||
|
|
m_buffer.contains( "NT_STATUS_LOGON_FAILURE" ) != 0 ||
|
|
m_buffer.contains( "The username or password was not correct" ) != 0 )
|
|
{
|
|
// Authentication failed:
|
|
emit failed();
|
|
|
|
if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(),
|
|
TQString(), Smb4KPasswordHandler::AccessDenied,
|
|
kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4" ).tqarg( Hosts ).tqarg( m_priv->workgroup(), m_priv->host(), m_priv->ip() ) ) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
else if ( m_buffer.contains( "Could not connect to server" ) != 0 ||
|
|
m_buffer.contains( "Unable to find a suitable server" ) != 0 ||
|
|
m_buffer.contains( "Invalid ip address specified" ) != 0 )
|
|
{
|
|
// We are in IP scan mode, so we can ignore the error and emit
|
|
// what we already have:
|
|
emit members( m_priv->workgroup(), *m_hosts_list );
|
|
emit hostListChanged();
|
|
|
|
return;
|
|
}
|
|
|
|
// We will not remove any host from the list in IP scan mode,
|
|
// but we will add additional infomation, if available.
|
|
|
|
bool process = false;
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).stripWhiteSpace().startsWith( "-------------" ) )
|
|
{
|
|
process = true;
|
|
|
|
continue;
|
|
}
|
|
|
|
if ( process && !(*it).stripWhiteSpace().isEmpty() )
|
|
{
|
|
TQString line = (*it).stripWhiteSpace();
|
|
|
|
// Extract host name and comment:
|
|
TQString host, comment;
|
|
|
|
if ( line.contains( " " ) == 0 )
|
|
{
|
|
host = line;
|
|
}
|
|
else
|
|
{
|
|
host = line.section( " ", 0, 0 ).stripWhiteSpace();
|
|
comment = line.section( " ", 1, -1 ).stripWhiteSpace();
|
|
}
|
|
|
|
// Now add the comment to the host item or do nothing if
|
|
// no comment was found:
|
|
if ( !comment.isEmpty() )
|
|
{
|
|
Smb4KHostItem *item = getHost( host, m_priv->workgroup() );
|
|
|
|
if ( item )
|
|
{
|
|
item->setComment( comment );
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
emit members( m_priv->workgroup(), *m_hosts_list );
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
emit hostListChanged();
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the share list of a host.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processShares()
|
|
{
|
|
// Error handling
|
|
if ( m_buffer.contains( "The username or password was not correct.", true ) != 0 ||
|
|
m_buffer.contains( "NT_STATUS_ACCOUNT_DISABLED" ) != 0 /* Active Directory error */ )
|
|
{
|
|
// Authentication failed:
|
|
emit failed();
|
|
|
|
if ( passwordHandler()->askpass( m_priv->workgroup(), m_priv->host(), TQString(), Smb4KPasswordHandler::AccessDenied, kapp->mainWidget() ? kapp->mainWidget() : 0, "AskPass" ) )
|
|
{
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4:%5" ).tqarg( Shares ).tqarg( m_priv->workgroup(), m_priv->host(), m_priv->ip(), TQString() ) ) );
|
|
}
|
|
|
|
return;
|
|
}
|
|
else if ( m_buffer.contains( "could not obtain sid for domain", true ) != 0 )
|
|
{
|
|
// FIXME: Does this error only occur when we scan a server that is
|
|
// only capable of the RAP protocol or also under other conditions?
|
|
m_queue.enqueue( new TQString( TQString( "%1:%2:%3:%4:%5" ).tqarg( Shares ).tqarg( m_priv->workgroup(), m_priv->host(), m_priv->ip(), "rap" ) ) );
|
|
|
|
m_priv->retry = true;
|
|
|
|
return;
|
|
}
|
|
else if ( (m_buffer.contains( "Could not connect to server", true ) != 0 &&
|
|
m_buffer.contains( "The username or password was not correct.", true ) == 0) ||
|
|
m_buffer.contains( "Unable to find a suitable server" ) != 0 )
|
|
{
|
|
// We could not get the list of shares:
|
|
emit failed();
|
|
|
|
// Notify the user:
|
|
Smb4KError::error( ERROR_GETTING_SHARES, TQString(), m_buffer );
|
|
|
|
return;
|
|
}
|
|
|
|
TQStringList list = TQStringList::split( '\n', m_buffer, false );
|
|
|
|
TQValueList<Smb4KShareItem *> share_list;
|
|
|
|
bool process = false;
|
|
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).startsWith( "---" ) )
|
|
{
|
|
process = true;
|
|
}
|
|
|
|
if ( process )
|
|
{
|
|
TQString name, type, comment;
|
|
|
|
if ( (*it).contains( " Disk ", true ) != 0 )
|
|
{
|
|
name = (*it).section( " Disk ", 0, 0 ).stripWhiteSpace();
|
|
type = "Disk";
|
|
comment = (*it).section( " Disk ", 1, 1 ).stripWhiteSpace();
|
|
}
|
|
else if ( (*it).contains( " Print ", true ) != 0 )
|
|
{
|
|
name = (*it).section( " Print ", 0, 0 ).stripWhiteSpace();
|
|
type = "Printer";
|
|
comment = (*it).section( " Print ", 1, 1 ).stripWhiteSpace();
|
|
}
|
|
else if ( (*it).contains( " IPC ", true ) != 0 )
|
|
{
|
|
name = (*it).section( " IPC ", 0, 0 ).stripWhiteSpace();
|
|
type = "IPC";
|
|
comment = (*it).section( " IPC ", 1, 1 ).stripWhiteSpace();
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
|
|
share_list.append( new Smb4KShareItem( m_priv->workgroup(), m_priv->host(), name, type, comment ) );
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
emit shares( m_priv->host(), share_list );
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the search data.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processSearch()
|
|
{
|
|
// NOTE: We do not emit Smb4KScanner::failed() here, because
|
|
// errors are handled in a different way by the search dialog.
|
|
|
|
// Stop right here if the user searched for illegal
|
|
// strings like #, ', () etc.
|
|
if ( m_buffer.contains( "Usage:", true ) != 0 ||
|
|
m_buffer.contains( "/bin/sh:", true ) != 0 )
|
|
{
|
|
emit searchResult( new Smb4KHostItem() );
|
|
|
|
return;
|
|
}
|
|
|
|
TQStringList data = TQStringList::split( '\n', m_buffer.stripWhiteSpace(), false );
|
|
|
|
switch ( Smb4KSettings::searchMethod() )
|
|
{
|
|
case Smb4KSettings::EnumSearchMethod::Nmblookup:
|
|
{
|
|
if ( !data.isEmpty() )
|
|
{
|
|
// The last entry in the list is the workgroup:
|
|
TQString workgroup = data.last().stripWhiteSpace();
|
|
TQString host, ip;
|
|
|
|
if ( m_priv->host().contains( ".", true ) != 3 )
|
|
{
|
|
// The IP address is in the first entry:
|
|
ip = data.first().stripWhiteSpace().section( " ", 0, 0 );
|
|
// The host.
|
|
host = m_priv->host().upper();
|
|
}
|
|
else
|
|
{
|
|
ip = m_priv->host();
|
|
host = data[0].stripWhiteSpace();
|
|
}
|
|
|
|
emit searchResult( new Smb4KHostItem( workgroup, host, TQString(), ip ) );
|
|
}
|
|
else
|
|
{
|
|
emit searchResult( new Smb4KHostItem() );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case Smb4KSettings::EnumSearchMethod::Smbclient:
|
|
{
|
|
if ( data.count() > 1 && !data[1].isEmpty() )
|
|
{
|
|
if ( m_buffer.contains( TQString( "Connection to %1 failed" ).tqarg( m_priv->host() ) ) != 0 )
|
|
{
|
|
emit searchResult( new Smb4KHostItem() );
|
|
}
|
|
else
|
|
{
|
|
TQString workgroup = data.grep( "Domain" ).first().section( "Domain=[", 1, 1 ).section( "]", 0, 0 );
|
|
TQString ip = data.grep( "Got a positive name query" ).first().section( "(", 1, 1 ).section( ")", 0, 0 ).stripWhiteSpace();
|
|
|
|
emit searchResult( new Smb4KHostItem( workgroup, m_priv->host().upper(), TQString(), ip ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
emit searchResult( new Smb4KHostItem() );
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Process the information about a host.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::processInfo()
|
|
{
|
|
if ( m_proc->normalExit() )
|
|
{
|
|
TQStringList list = TQStringList::split( '\n', m_buffer, false );
|
|
|
|
Smb4KHostItem *host = getHost( m_priv->host(), m_priv->workgroup() );
|
|
|
|
if ( host )
|
|
{
|
|
for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
|
|
{
|
|
if ( (*it).stripWhiteSpace().startsWith( "Domain" ) || (*it).stripWhiteSpace().startsWith( "OS" ) )
|
|
{
|
|
// The OS string.
|
|
host->setOSString( (*it).section( "OS=[", 1, 1 ).section( "]", 0, 0 ).stripWhiteSpace() );
|
|
|
|
// The Server string.
|
|
host->setServerString( (*it).section( "Server=[", 1, 1 ).section( "]", 0, 0 ).stripWhiteSpace() );
|
|
|
|
break;
|
|
}
|
|
else if ( (*it).contains( "Connection to", true ) != 0 )
|
|
{
|
|
// The lookup of the info failed:
|
|
emit failed();
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
emit info( host );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// In case the process was aborted, we need to enable checking
|
|
// again:
|
|
Smb4KHostItem *host = getHost( m_priv->host(), m_priv->workgroup() );
|
|
|
|
if ( host )
|
|
{
|
|
host->setInfoChecked( false );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Get a workgroup item out of the workgroup list.
|
|
****************************************************************************/
|
|
|
|
Smb4KWorkgroupItem *Smb4KScanner::getWorkgroup( const TQString &workgroup )
|
|
{
|
|
TQValueListIterator<Smb4KWorkgroupItem *> it;
|
|
|
|
for ( it = m_workgroups_list->begin(); it != m_workgroups_list->end(); ++it )
|
|
{
|
|
if ( TQString::compare( (*it)->name(), workgroup ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return it == m_workgroups_list->end() ? NULL : *it;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Get a workgroup item out of the workgroup list.
|
|
****************************************************************************/
|
|
|
|
Smb4KHostItem *Smb4KScanner::getHost( const TQString &name, const TQString &workgroup )
|
|
{
|
|
TQValueListIterator<Smb4KHostItem *> it;
|
|
|
|
for ( it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
if ( !workgroup.stripWhiteSpace().isEmpty() &&
|
|
TQString::compare( (*it)->workgroup().upper(), workgroup.upper() ) != 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( TQString::compare( (*it)->name().upper(), name.upper() ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return it == m_hosts_list->end() ? NULL : *it;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Add a host to the host list
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::insertHost( Smb4KHostItem *host )
|
|
{
|
|
if ( host && !getHost( host->name(), host->workgroup() ) )
|
|
{
|
|
// Use the copy constructor here, so that we do not run into
|
|
// trouble when/if host is deleted.
|
|
Smb4KHostItem *host_item = new Smb4KHostItem( *host );
|
|
|
|
m_hosts_list->append( host_item );
|
|
|
|
// Check if the workgroup is already known. If not, create a new Smb4KWorkgroupItem,
|
|
// declare the host a pseudo master and add the workgroup to the list.
|
|
if ( !getWorkgroup( host_item->workgroup() ) )
|
|
{
|
|
Smb4KWorkgroupItem *workgroup_item = new Smb4KWorkgroupItem( host_item->workgroup(),
|
|
host_item->name(), host_item->ip() );
|
|
workgroup_item->setPseudoMaster();
|
|
host_item->setMaster( true ); // pseudo master
|
|
|
|
appendWorkgroup( workgroup_item );
|
|
}
|
|
|
|
// Lookup at least the IP address of this host, if necessary:
|
|
if ( host_item->ip().isEmpty() )
|
|
{
|
|
lookupIPAddresses();
|
|
}
|
|
|
|
emit hostAdded( host_item );
|
|
|
|
emit hostListChanged();
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Appends an item to the list of workgroups.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::appendWorkgroup( Smb4KWorkgroupItem *item )
|
|
{
|
|
if ( !getWorkgroup( item->name() ) )
|
|
{
|
|
m_workgroups_list->append( item );
|
|
|
|
emit workgroups( *m_workgroups_list );
|
|
}
|
|
}
|
|
|
|
|
|
void Smb4KScanner::timerEvent( TQTimerEvent * )
|
|
{
|
|
// Look for the thing to do (next).
|
|
// At this point, the topmost item will not be
|
|
// dequeued. This will be done below.
|
|
int todo = Idle;
|
|
TQString *head = NULL;
|
|
|
|
if ( (head = m_queue.head()) != 0 )
|
|
{
|
|
todo = head->section( ":", 0, 0 ).toInt();
|
|
}
|
|
|
|
if ( !m_working && !m_queue.isEmpty() )
|
|
{
|
|
// Start processing with dequeueing the item:
|
|
TQString *item = m_queue.dequeue();
|
|
|
|
// Tell the program, that the scanner is running.
|
|
m_working = true;
|
|
|
|
switch ( todo )
|
|
{
|
|
case Init:
|
|
{
|
|
emit state( SCANNER_INIT );
|
|
scanNetwork();
|
|
break;
|
|
}
|
|
case Hosts:
|
|
{
|
|
emit state( SCANNER_OPENING_WORKGROUP );
|
|
scanForWorkgroupMembers( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ) );
|
|
break;
|
|
}
|
|
case Shares:
|
|
{
|
|
if ( !m_priv->retry )
|
|
{
|
|
emit state( SCANNER_OPENING_HOST );
|
|
}
|
|
else
|
|
{
|
|
emit state( SCANNER_RETRYING_OPENING_HOST );
|
|
m_priv->retry = false;
|
|
}
|
|
scanForShares( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ), item->section( ":", 4, 4 ) );
|
|
break;
|
|
}
|
|
case Info:
|
|
{
|
|
emit state( SCANNER_RETRIEVING_INFO );
|
|
scanForInfo( item->section( ":", 1, 1 ), item->section( ":", 2, 2 ), item->section( ":", 3, 3 ) );
|
|
break;
|
|
}
|
|
case Search:
|
|
{
|
|
emit state( SCANNER_SEARCHING );
|
|
searchForHost( item->section( ":", 1, 1 ) );
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
delete item;
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// TQT_SLOT IMPLEMENTATIONS
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/****************************************************************************
|
|
Internal slots.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::slotReceivedStdout( KProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
}
|
|
|
|
|
|
void Smb4KScanner::slotProcessExited( KProcess * )
|
|
{
|
|
endProcess();
|
|
}
|
|
|
|
|
|
void Smb4KScanner::slotReceivedStderr( KProcess *, char *buf, int len )
|
|
{
|
|
m_buffer.append( TQString::fromLocal8Bit( buf, len ) );
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* Lookup for IP addresses *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
/****************************************************************************
|
|
Start the scanning for IP addresses
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::lookupIPAddresses()
|
|
{
|
|
bool start = false;
|
|
TQString command = TQString();
|
|
|
|
for ( TQValueList<Smb4KHostItem *>::ConstIterator it = m_hosts_list->begin(); it != m_hosts_list->end(); ++it )
|
|
{
|
|
if ( (*it)->ip().stripWhiteSpace().isEmpty() && !(*it)->ipAddressChecked() )
|
|
{
|
|
if ( !start )
|
|
{
|
|
start = true;
|
|
}
|
|
|
|
(*it)->setIPAddressChecked( true );
|
|
|
|
command.append( "nmblookup" );
|
|
command.append( optionsHandler()->nmblookupOptions() );
|
|
command.append( optionsHandler()->winsServer().isEmpty() ? "" : " -R -U "+KProcess::quote( optionsHandler()->winsServer() ) );
|
|
command.append( " -- "+KProcess::quote( (*it)->name() )+" | grep '<00>'" );
|
|
command.append( " ; " );
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
command.truncate( command.length() - 3 );
|
|
|
|
if ( start )
|
|
{
|
|
KProcess *proc = new KProcess( this );
|
|
proc->setUseShell( true );
|
|
|
|
connect( proc, TQT_SIGNAL( receivedStdout( KProcess *, char *, int ) ),
|
|
this, TQT_SLOT( slotReceivedIPAddresses( KProcess *, char *, int ) ) );
|
|
connect( proc, TQT_SIGNAL( processExited( KProcess * ) ),
|
|
this, TQT_SLOT( slotIPAddressProcessExited( KProcess * ) ) );
|
|
|
|
*proc << command;
|
|
proc->start( KProcess::NotifyOnExit, KProcess::Stdout );
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Processes IP addresses if data occurrs on stdout.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::slotReceivedIPAddresses( KProcess *, char *buf, int len )
|
|
{
|
|
// WARNING: Do not implement error handling here!!!
|
|
|
|
TQString buffer = TQString::fromLocal8Bit( buf, len );
|
|
|
|
if ( !buffer.stripWhiteSpace().isEmpty() )
|
|
{
|
|
TQString ip = buffer.stripWhiteSpace().section( " ", 0, 0 ).stripWhiteSpace();
|
|
TQString host = buffer.stripWhiteSpace().section( " ", 1, 1 ).section( "<00>", 0, 0 ).stripWhiteSpace();
|
|
|
|
if ( !host.isEmpty() && !ip.isEmpty() )
|
|
{
|
|
Smb4KHostItem *item = getHost( host );
|
|
|
|
if ( item )
|
|
{
|
|
item->setIPAddress( ip );
|
|
|
|
if ( item->isMaster() )
|
|
{
|
|
Smb4KWorkgroupItem *workgroup = getWorkgroup( item->workgroup() );
|
|
|
|
if ( workgroup )
|
|
{
|
|
workgroup->setMasterIP( ip );
|
|
}
|
|
}
|
|
|
|
emit ipAddress( item );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
End IP address scan.
|
|
****************************************************************************/
|
|
|
|
void Smb4KScanner::slotIPAddressProcessExited( KProcess *p )
|
|
{
|
|
delete p;
|
|
}
|
|
|
|
|
|
#include "smb4kscanner.moc"
|