20
20
* You should have received a copy of the GNU General Public License *
21
21
* along with this program; if not, write to the *
22
* Free Software Foundation, 51 Franklin Street, Suite 500, Boston, *
22
* Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
23
23
* MA 02110-1335, USA *
24
24
***************************************************************************/
30
// application specific includes
31
#include "smb4kscanner_p.h"
32
#include "smb4ksettings.h"
33
#include "smb4knotification.h"
34
#include "smb4kglobal.h"
35
#include "smb4kcustomoptionsmanager.h"
36
#include "smb4kcustomoptions.h"
37
#include "smb4kworkgroup.h"
38
#include "smb4khost.h"
39
#include "smb4kshare.h"
40
#include "smb4kwalletmanager.h"
29
#include <QHostAddress>
30
#include <QAbstractSocket>
43
#include <QtCore/QTimer>
44
#include <QtCore/QDebug>
45
#include <QtCore/QLatin1String>
46
#include <QtNetwork/QHostAddress>
47
#include <QtNetwork/QAbstractSocket>
33
50
#include <kstandarddirs.h>
34
51
#include <kshell.h>
36
// application specific includes
37
#include <smb4kscanner_p.h>
38
#include <smb4ksettings.h>
39
#include <smb4knotification.h>
40
#include <smb4kglobal.h>
41
#include <smb4kcustomoptionsmanager.h>
42
#include <smb4kcustomoptions.h>
43
#include <smb4kworkgroup.h>
44
#include <smb4khost.h>
45
#include <smb4kshare.h>
46
#include <smb4kwalletmanager.h>
48
53
using namespace Smb4KGlobal;
1521
1562
void Smb4KLookupDomainMembersJob::processHosts()
1523
QStringList stdout = QString::fromUtf8( m_proc->readAllStandardOutput(), -1 ).split( "\n", QString::SkipEmptyParts );
1564
QStringList stdout = QString::fromUtf8( m_proc->readAllStandardOutput(), -1 ).split( '\n', QString::SkipEmptyParts );
1525
1566
if ( !stdout.isEmpty() )
1568
Smb4KHost *host = new Smb4KHost();
1529
1570
foreach ( const QString &line, stdout )
1531
if ( line.trimmed().startsWith( "Enumerating" ) )
1535
else if ( line.trimmed().startsWith( "Server name" ) )
1539
else if ( line.trimmed().startsWith( "-------------" ) )
1572
if ( line.trimmed().startsWith( QLatin1String( "Enumerating" ) ) )
1576
else if ( line.trimmed().startsWith( QLatin1String( "Server name" ) ) )
1580
else if ( line.trimmed().startsWith( QLatin1String( "-------------" ) ) )
1545
// Omit host names that contain spaces since QUrl cannot handle them.
1586
// Omit host names that contain spaces since KUrl cannot handle them.
1546
1587
// And, they are wrong, anyway.
1547
1588
if ( !line.section( " ", 0, 0 ).trimmed().contains( " " ) )
1549
host.setHostName( line.section( " ", 0, 0 ).trimmed() );
1550
host.setWorkgroupName( m_workgroup.workgroupName() );
1551
host.setComment( line.section( " ", 1, -1 ).trimmed() );
1590
host->setHostName( line.section( " ", 0, 0 ).trimmed() );
1591
host->setWorkgroupName( m_workgroup->workgroupName() );
1592
host->setComment( line.section( " ", 1, -1 ).trimmed() );
1553
if ( QString::compare( host.hostName(), m_workgroup.masterBrowserName() ) == 0 )
1594
if ( QString::compare( host->hostName(), m_workgroup->masterBrowserName() ) == 0 )
1555
host.setLogin( m_master_browser.login() );
1556
host.setPassword( m_master_browser.password() );
1557
host.setIsMasterBrowser( true );
1596
host->setLogin( m_master_browser->login() );
1597
host->setPassword( m_master_browser->password() );
1598
host->setIsMasterBrowser( true );
1559
if ( m_workgroup.hasMasterBrowserIP() )
1600
if ( m_workgroup->hasMasterBrowserIP() )
1561
host.setIP( m_workgroup.masterBrowserIP() );
1602
host->setIP( m_workgroup->masterBrowserIP() );
1719
1763
m_proc->setShellCommand( arguments.join( " " ) );
1720
1764
m_proc->setOutputChannelMode( KProcess::SeparateChannels );
1722
if ( Smb4KSettings::self()->masterBrowsersRequireAuth() && !m_master_browser.password().isEmpty() )
1766
if ( Smb4KSettings::self()->masterBrowsersRequireAuth() && !m_master_browser->password().isEmpty() )
1724
m_proc->setEnv( "PASSWD", m_master_browser.password(), true );
1768
m_proc->setEnv( "PASSWD", m_master_browser->password(), true );
1728
1772
m_proc->unsetEnv( "PASSWD" );
1731
connect( m_proc, SIGNAL( readyReadStandardError() ), SLOT( slotReadStandardError() ) );
1732
connect( m_proc, SIGNAL( finished( int, QProcess::ExitStatus ) ), SLOT( slotProcessFinished( int, QProcess::ExitStatus ) ) );
1775
connect( m_proc, SIGNAL(readyReadStandardError()), SLOT(slotReadStandardError()) );
1776
connect( m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
1734
emit aboutToStart( &m_workgroup );
1778
emit aboutToStart( m_workgroup );
1736
1780
m_proc->start();
1740
1784
// The master browser could not be determined. End the
1741
// job here and emit an empty hosts list.
1742
emit hosts( &m_workgroup, m_hosts_list );
1785
// job here and emit the signal nontheless.
1786
emit hosts( m_workgroup, m_hosts_list );
1880
1930
void Smb4KLookupSharesJob::processShares()
1882
// Additional authentication error handling.
1883
if ( m_proc->exitCode() == 104 /* access denied in W2k3 domain */ ||
1884
m_proc->exitCode() == 235 /* wrong password in W2k3 domain */ )
1886
emit authError( this );
1887
// We can just return here, because this function is invoked
1888
// in slotProcessFinished() and emitResult() will be emitted
1897
QStringList stdout = QString::fromUtf8( m_proc->readAllStandardOutput(), -1 ).split( "\n", QString::SkipEmptyParts );
1932
QStringList stdout = QString::fromUtf8( m_proc->readAllStandardOutput(), -1 ).split( '\n', QString::SkipEmptyParts );
1899
1934
if ( !stdout.isEmpty() )
1936
Smb4KShare *share = new Smb4KShare();
1903
1938
foreach ( const QString &line, stdout )
1905
if ( line.trimmed().startsWith( "Enumerating" ) )
1909
else if ( line.trimmed().startsWith( "Share name" ) )
1913
else if ( line.trimmed().startsWith( "----------" ) )
1940
if ( line.trimmed().startsWith( QLatin1String( "Enumerating" ) ) )
1944
else if ( line.trimmed().startsWith( QLatin1String( "Share name" ) ) )
1948
else if ( line.trimmed().startsWith( QLatin1String( "----------" ) ) )
1917
1952
else if ( line.contains( " Disk ", Qt::CaseSensitive ) /* line has comment */ ||
1918
1953
(!line.contains( " Disk ", Qt::CaseSensitive ) &&
1919
line.trimmed().endsWith( " Disk", Qt::CaseSensitive ) /* line has no comment */) )
1954
line.trimmed().endsWith( QLatin1String( " Disk" ), Qt::CaseSensitive ) /* line has no comment */) )
1921
if ( !line.trimmed().endsWith( " Disk", Qt::CaseSensitive ) )
1956
if ( !line.trimmed().endsWith( QLatin1String( " Disk" ), Qt::CaseSensitive ) )
1923
share.setShareName( line.section( " Disk ", 0, 0 ).trimmed() );
1924
share.setComment( line.section( " Disk ", 1, 1 ).trimmed() );
1958
share->setShareName( line.section( " Disk ", 0, 0 ).trimmed() );
1959
share->setComment( line.section( " Disk ", 1, 1 ).trimmed() );
1928
share.setShareName( line.section( " Disk", 0, 0 ).trimmed() );
1929
share.setComment( "" );
1963
share->setShareName( line.section( " Disk", 0, 0 ).trimmed() );
1964
share->setComment( "" );
1932
share.setHostName( m_host.hostName() );
1933
share.setWorkgroupName( m_host.workgroupName() );
1934
share.setTypeString( "Disk" );
1935
share.setLogin( m_host.login() );
1936
share.setPassword( m_host.password() );
1967
share->setHostName( m_host->hostName() );
1968
share->setWorkgroupName( m_host->workgroupName() );
1969
share->setTypeString( "Disk" );
1970
share->setLogin( m_host->login() );
1971
share->setPassword( m_host->password() );
1938
if ( m_host.hasIP() )
1973
if ( m_host->hasIP() )
1940
share.setHostIP( m_host.ip() );
1975
share->setHostIP( m_host->ip() );
1947
m_shares_list << share;
1948
share = Smb4KShare();
1982
m_shares_list << new Smb4KShare( *share );
1985
share = new Smb4KShare();
1951
1989
else if ( line.contains( " IPC ", Qt::CaseSensitive ) /* line has comment */ ||
1952
1990
(!line.contains( " IPC ", Qt::CaseSensitive ) &&
1953
line.trimmed().endsWith( " IPC", Qt::CaseSensitive ) /* line has no comment */) )
1991
line.trimmed().endsWith( QLatin1String( " IPC" ), Qt::CaseSensitive ) /* line has no comment */) )
1955
if ( !line.trimmed().endsWith( " IPC", Qt::CaseSensitive ) )
1993
if ( !line.trimmed().endsWith( QLatin1String( " IPC" ), Qt::CaseSensitive ) )
1957
share.setShareName( line.section( " IPC ", 0, 0 ).trimmed() );
1958
share.setComment( line.section( " IPC ", 1, 1 ).trimmed() );
1995
share->setShareName( line.section( " IPC ", 0, 0 ).trimmed() );
1996
share->setComment( line.section( " IPC ", 1, 1 ).trimmed() );
1962
share.setShareName( line.section( " IPC", 0, 0 ).trimmed() );
1963
share.setComment( "" );
2000
share->setShareName( line.section( " IPC", 0, 0 ).trimmed() );
2001
share->setComment( "" );
1966
share.setHostName( m_host.hostName() );
1967
share.setWorkgroupName( m_host.workgroupName() );
1968
share.setTypeString( "IPC" );
1969
share.setLogin( m_host.login() );
1970
share.setPassword( m_host.password() );
2004
share->setHostName( m_host->hostName() );
2005
share->setWorkgroupName( m_host->workgroupName() );
2006
share->setTypeString( "IPC" );
2007
share->setLogin( m_host->login() );
2008
share->setPassword( m_host->password() );
1972
if ( m_host.hasIP() )
2010
if ( m_host->hasIP() )
1974
share.setHostIP( m_host.ip() );
2012
share->setHostIP( m_host->ip() );
1981
m_shares_list << share;
1982
share = Smb4KShare();
2019
m_shares_list << new Smb4KShare( *share );
2022
share = new Smb4KShare();
1985
2026
else if ( line.contains( " Print ", Qt::CaseSensitive ) /* line has comment */ ||
1986
2027
(!line.contains( " Print ", Qt::CaseSensitive ) &&
1987
line.trimmed().endsWith( " Print", Qt::CaseSensitive ) /* line has no comment */) )
2028
line.trimmed().endsWith( QLatin1String( " Print" ), Qt::CaseSensitive ) /* line has no comment */) )
1989
if ( !line.trimmed().endsWith( " Print", Qt::CaseSensitive ) )
2030
if ( !line.trimmed().endsWith( QLatin1String( " Print" ), Qt::CaseSensitive ) )
1991
share.setShareName( line.section( " Print ", 0, 0 ).trimmed() );
1992
share.setComment( line.section( " Print ", 1, 1 ).trimmed() );
2032
share->setShareName( line.section( " Print ", 0, 0 ).trimmed() );
2033
share->setComment( line.section( " Print ", 1, 1 ).trimmed() );
1996
share.setShareName( line.section( " Print", 0, 0 ).trimmed() );
1997
share.setComment( "" );
2037
share->setShareName( line.section( " Print", 0, 0 ).trimmed() );
2038
share->setComment( "" );
2000
share.setHostName( m_host.hostName() );
2001
share.setWorkgroupName( m_host.workgroupName() );
2002
share.setTypeString( "Printer" );
2003
share.setLogin( m_host.login() );
2004
share.setPassword( m_host.password() );
2041
share->setHostName( m_host->hostName() );
2042
share->setWorkgroupName( m_host->workgroupName() );
2043
share->setTypeString( "Printer" );
2044
share->setLogin( m_host->login() );
2045
share->setPassword( m_host->password() );
2006
if ( m_host.hasIP() )
2047
if ( m_host->hasIP() )
2008
share.setHostIP( m_host.ip() );
2049
share->setHostIP( m_host->ip() );
2015
m_shares_list << share;
2016
share = Smb4KShare();
2056
m_shares_list << new Smb4KShare( *share );
2059
share = new Smb4KShare();
2199
2245
m_proc->setOutputChannelMode( KProcess::SeparateChannels );
2200
2246
m_proc->setShellCommand( arguments.join( " " ) );
2202
if ( !m_host.password().isEmpty() )
2248
if ( !m_host->password().isEmpty() )
2204
m_proc->setEnv( "PASSWD", m_host.password(), true );
2250
m_proc->setEnv( "PASSWD", m_host->password(), true );
2208
2254
m_proc->unsetEnv( "PASSWD" );
2211
connect( m_proc, SIGNAL( readyReadStandardError() ), this, SLOT( slotReadStandardError() ) );
2212
connect( m_proc, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( slotProcessFinished( int, QProcess::ExitStatus ) ) );
2257
connect( m_proc, SIGNAL(readyReadStandardError()), this, SLOT(slotReadStandardError()) );
2258
connect( m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
2214
emit aboutToStart( &m_host );
2260
emit aboutToStart( m_host );
2216
2262
m_proc->start();
2659
emit finished( &m_host );
2665
Smb4KScannerPrivate::Smb4KScannerPrivate()
2670
Smb4KScannerPrivate::~Smb4KScannerPrivate()
2706
emit finished( m_host );
2711
Smb4KLookupIPAddressJob::Smb4KLookupIPAddressJob( QObject *parent )
2712
: KJob( parent ), m_started( false ), m_host( NULL ), m_parent_widget( NULL ), m_proc( NULL )
2717
Smb4KLookupIPAddressJob::~Smb4KLookupIPAddressJob()
2723
void Smb4KLookupIPAddressJob::start()
2726
QTimer::singleShot( 0, this, SLOT(slotStartLookup()) );
2730
void Smb4KLookupIPAddressJob::setupLookup( Smb4KHost *host, QWidget *parent )
2733
m_host = new Smb4KHost( *host );
2734
m_parent_widget = parent;
2738
bool Smb4KLookupIPAddressJob::doKill()
2740
if ( m_proc && (m_proc->state() == KProcess::Running || m_proc->state() == KProcess::Starting) )
2749
return KJob::doKill();
2753
void Smb4KLookupIPAddressJob::processIPAddress()
2755
// Normally, there should only be one IP address. However, there might
2756
// be more than one. So, split the incoming data and use the first entry
2757
// as IP address (it's most likely the correct one). If there is no data,
2758
// set the IP address to an empty string.
2759
QStringList output = QString::fromUtf8( m_proc->readAllStandardOutput(), -1 ).split( '\n', QString::SkipEmptyParts );
2761
foreach ( const QString &line, output )
2763
if ( line.contains( "<00>" ) )
2765
QString ip_address = line.section( ' ', 0, 0 ).trimmed();
2766
m_host->setIP( ip_address );
2775
emit ipAddress( m_host );
2779
void Smb4KLookupIPAddressJob::slotStartLookup()
2781
// Find nmblookup program.
2782
QString nmblookup = KStandardDirs::findExe( "nmblookup" );
2784
if ( nmblookup.isEmpty() )
2786
Smb4KNotification *notification = new Smb4KNotification();
2787
notification->commandNotFound( "nmblookup" );
2796
// Global Samba options
2797
QMap<QString,QString> samba_options = globalSambaOptions();
2799
// Compile the arguments
2800
QStringList arguments;
2801
arguments << nmblookup;
2804
if ( !Smb4KSettings::domainName().isEmpty() &&
2805
QString::compare( Smb4KSettings::domainName(), samba_options["workgroup"] ) != 0 )
2807
arguments << QString( "-W %1" ).arg( KShell::quoteArg( Smb4KSettings::domainName() ) );
2815
if ( !Smb4KSettings::netBIOSName().isEmpty() &&
2816
QString::compare( Smb4KSettings::netBIOSName(), samba_options["netbios name"] ) != 0 )
2818
arguments << QString( "-n %1" ).arg( KShell::quoteArg( Smb4KSettings::netBIOSName() ) );
2826
if ( !Smb4KSettings::netBIOSScope().isEmpty() &&
2827
QString::compare( Smb4KSettings::netBIOSScope(), samba_options["netbios scope"] ) != 0 )
2829
arguments << QString( "-i %1" ).arg( KShell::quoteArg( Smb4KSettings::netBIOSScope() ) );
2837
if ( !Smb4KSettings::socketOptions().isEmpty() &&
2838
QString::compare( Smb4KSettings::socketOptions(), samba_options["socket options"] ) != 0 )
2840
arguments << QString( "-O %1" ).arg( KShell::quoteArg( Smb4KSettings::socketOptions() ) );
2848
if ( Smb4KSettings::usePort137() )
2857
// Broadcast address
2858
QHostAddress address( Smb4KSettings::broadcastAddress() );
2860
if ( !Smb4KSettings::broadcastAddress().isEmpty() &&
2861
address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol )
2863
arguments << QString( "-B %1" ).arg( Smb4KSettings::broadcastAddress() );
2870
// We do not use the WINS server here, because it emerged that using
2871
// the WINS server is sometimes not very reliable.
2874
if ( !winsServer().isEmpty() )
2877
arguments << QString( "-U %1" ).arg( KShell::quoteArg( winsServer() ) );
2885
arguments << KShell::quoteArg( m_host->hostName() );
2887
m_proc = new Smb4KProcess( this );
2888
m_proc->setOutputChannelMode( KProcess::SeparateChannels );
2889
m_proc->setShellCommand( arguments.join( " " ) );
2891
connect( m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)) );
2897
void Smb4KLookupIPAddressJob::slotProcessFinished( int /*exitCode*/, QProcess::ExitStatus exitStatus )
2899
switch ( exitStatus )
2901
case QProcess::CrashExit:
2903
if ( !m_proc->isAborted() )
2905
Smb4KNotification *notification = new Smb4KNotification();
2906
notification->processError( m_proc->error() );
2675
2926
#include "smb4kscanner_p.moc"