~ubuntu-branches/ubuntu/quantal/smb4k/quantal

« back to all changes in this revision

Viewing changes to core/smb4kscanner.cpp

  • Committer: Package Import Robot
  • Author(s): Fathi Boudra
  • Date: 2012-05-19 18:54:34 UTC
  • mfrom: (1.1.20)
  • Revision ID: package-import@ubuntu.com-20120519185434-duffny2n87214n1n
Tags: 1.0.1-1
* New upstream release.
* Update debian/compat: bump to 9.
* Update debian/control:
  - bump debhelper to 9.
  - bump kdelibs5-dev build dependency to 4:4.4.0.
  - bump Standards-Version to 3.9.3 (no changes needed).
  - Replace smbfs dependency by cifs-utils. (Closes: #638162)
* Update debian/copyright:
  - update upstream URL.
  - update upstream e-mail.
* Update debian/smb4k.lintian-overrides file.
* Update debian/watch file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
    smb4kscanner.cpp  -  The network scan core class of Smb4K.
 
2
    smb4kscanner  -  This class retrieves all workgroups, servers and
 
3
    shares found on the network neighborhood
3
4
                             -------------------
4
 
    begin                : Sam Mai 31 2003
5
 
    copyright            : (C) 2003-2008 by Alexander Reinholdt
6
 
    email                : dustpuppy@users.berlios.de
 
5
    begin                : So Mai 22 2011
 
6
    copyright            : (C) 2011 by Alexander Reinholdt
 
7
    email                : alexander.reinholdt@kdemail.net
7
8
 ***************************************************************************/
8
9
 
9
10
/***************************************************************************
19
20
 *                                                                         *
20
21
 *   You should have received a copy of the GNU General Public License     *
21
22
 *   along with this program; if not, write to the                         *
22
 
 *   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,   *
23
 
 *   MA  02111-1307 USA                                                    *
 
23
 *   Free Software Foundation, 51 Franklin Street, Suite 500, Boston,      *
 
24
 *   MA 02110-1335, USA                                                    *
24
25
 ***************************************************************************/
25
26
 
26
27
// Qt includes
27
 
#include <QApplication>
28
 
#include <QMap>
 
28
#include <QTimer>
29
29
#include <QHostAddress>
30
30
#include <QAbstractSocket>
31
 
#include <QDesktopWidget>
32
31
 
33
32
// KDE includes
34
 
#include <klocale.h>
 
33
#include <kglobal.h>
35
34
#include <kapplication.h>
36
 
#include <kdebug.h>
37
 
#include <kshell.h>
38
 
 
39
 
// system includes
40
 
#include <stdlib.h>
41
 
 
42
 
// Application specific includes.
 
35
 
 
36
// application specific includes
43
37
#include <smb4kscanner.h>
44
38
#include <smb4kscanner_p.h>
45
 
#include <smb4kauthinfo.h>
46
 
#include <smb4kcoremessage.h>
47
 
#include <smb4kglobal.h>
48
 
#include <smb4ksambaoptionshandler.h>
49
39
#include <smb4ksettings.h>
 
40
#include <smb4kbasicnetworkitem.h>
50
41
#include <smb4kworkgroup.h>
51
42
#include <smb4khost.h>
52
43
#include <smb4kshare.h>
 
44
#include <smb4kglobal.h>
53
45
#include <smb4kipaddressscanner.h>
54
 
#include <smb4khomesshareshandler.h>
 
46
#include <smb4kauthinfo.h>
55
47
#include <smb4kwalletmanager.h>
 
48
#include <smb4knotification.h>
56
49
 
57
50
using namespace Smb4KGlobal;
58
51
 
59
 
typedef Smb4KScannerQueueContainer QueueContainer;
60
 
 
61
 
 
62
 
Smb4KScanner::Smb4KScanner( QObject *parent )
63
 
: QObject( parent )
 
52
#define TIMER_INTERVAL 250
 
53
 
 
54
K_GLOBAL_STATIC( Smb4KScannerPrivate, p );
 
55
 
 
56
 
 
57
Smb4KScanner::Smb4KScanner() : KCompositeJob( 0 )
64
58
{
65
 
  m_priv = new Smb4KScannerPrivate;
66
 
 
67
 
  m_proc = new KProcess( this );
68
 
 
69
 
  m_working = false;
70
 
  m_aborted = false;
71
 
  m_process_error = (QProcess::ProcessError)(-1);
72
 
 
73
 
  connect( m_proc,  SIGNAL( finished( int, QProcess::ExitStatus ) ),
74
 
           this,    SLOT( slotProcessFinished( int, QProcess::ExitStatus ) )  );
75
 
 
76
 
  connect( m_proc,  SIGNAL( error( QProcess::ProcessError ) ),
77
 
           this,    SLOT( slotProcessError( QProcess::ProcessError ) ) );
78
 
 
79
 
  connect( Smb4KIPAddressScanner::self(), SIGNAL( ipAddress( Smb4KHost * ) ),
80
 
           this,                          SIGNAL( ipAddress( Smb4KHost * ) ) );
 
59
  setAutoDelete( false );
 
60
  
 
61
  m_interval = 0;
 
62
  m_scanning_allowed = true;
 
63
  
 
64
  connect( QCoreApplication::instance(), SIGNAL( aboutToQuit() ), SLOT( slotAboutToQuit() ) );
81
65
}
82
66
 
83
67
 
84
68
Smb4KScanner::~Smb4KScanner()
85
69
{
86
 
  abort();
87
 
 
88
 
  delete m_priv;
89
 
}
90
 
 
91
 
 
92
 
void Smb4KScanner::init()
93
 
{
94
 
  startTimer( TIMER_INTERVAL );
95
 
 
96
 
  rescan();
97
 
}
98
 
 
99
 
 
100
 
void Smb4KScanner::abort()
101
 
{
102
 
  while ( !m_queue.isEmpty() )
103
 
  {
104
 
    m_queue.dequeue();
105
 
  }
106
 
 
107
 
  if ( m_proc->state() == QProcess::Running )
108
 
  {
109
 
    m_proc->kill();
110
 
  }
111
 
 
112
 
  m_aborted = true;
113
 
}
114
 
 
115
 
 
116
 
void Smb4KScanner::rescan()
117
 
{
118
 
  m_queue.enqueue( QueueContainer( Init ) );
119
 
}
120
 
 
121
 
 
122
 
void Smb4KScanner::getWorkgroupMembers( Smb4KWorkgroup *workgroup )
123
 
{
124
 
  m_queue.enqueue( QueueContainer( Hosts, *workgroup ) );
125
 
}
126
 
 
127
 
 
128
 
void Smb4KScanner::getShares( Smb4KHost *host )
129
 
{
130
 
  m_queue.enqueue( QueueContainer( Shares, *host ) );
131
 
}
132
 
 
133
 
 
134
 
void Smb4KScanner::getInfo( Smb4KHost *host )
135
 
{
136
 
  Smb4KHost *known_host = findHost( host->name(), host->workgroup() );
137
 
 
 
70
}
 
71
 
 
72
 
 
73
Smb4KScanner *Smb4KScanner::self()
 
74
{
 
75
  return &p->instance;
 
76
}
 
77
 
 
78
 
 
79
bool Smb4KScanner::isRunning()
 
80
{
 
81
  return !subjobs().isEmpty();
 
82
}
 
83
 
 
84
 
 
85
bool Smb4KScanner::isRunning( Smb4KScanner::Process process, Smb4KBasicNetworkItem *item )
 
86
{
 
87
  bool running = false;
 
88
 
 
89
  switch ( process )
 
90
  {
 
91
    case LookupDomains:
 
92
    {
 
93
      // We do not need a network item with this kind
 
94
      // of process. We'll just test if at least on job labeled
 
95
      // 'LookupDomainsJob' or 'ScanBAreasJob' is running.
 
96
      for ( int i = 0; i < subjobs().size(); ++i )
 
97
      {
 
98
        if ( QString::compare( subjobs().at( i )->objectName(), "LookupDomainsJob" ) == 0 ||
 
99
             QString::compare( subjobs().at( i )->objectName(), "ScanBAreasJob" ) == 0 )
 
100
        {
 
101
          running = true;
 
102
          break;
 
103
        }
 
104
        else
 
105
        {
 
106
          continue;
 
107
        }
 
108
      }
 
109
      break;
 
110
    }
 
111
    case LookupDomainMembers:
 
112
    {
 
113
      if ( item && item->type() == Smb4KBasicNetworkItem::Workgroup )
 
114
      {
 
115
        // Only return TRUE if a job for the passed workgroup is running.
 
116
        Smb4KWorkgroup *workgroup = static_cast<Smb4KWorkgroup *>( item );
 
117
        
 
118
        if ( workgroup )
 
119
        {
 
120
          for ( int i = 0; i < subjobs().size(); ++i )
 
121
          {
 
122
            if ( QString::compare( subjobs().at( i )->objectName(),
 
123
                 QString( "LookupDomainMembersJob_%1" ).arg( workgroup->workgroupName() ), Qt::CaseInsensitive ) == 0 )
 
124
            {
 
125
              running = true;
 
126
              break;
 
127
            }
 
128
            else
 
129
            {
 
130
              continue;
 
131
            }
 
132
          }
 
133
        }
 
134
        else
 
135
        {
 
136
          // Do nothing --- This should not happen.
 
137
        }
 
138
      }
 
139
      else
 
140
      {
 
141
        // If no item is defined, we just loop through the subjobs
 
142
        // and search for a "LookupDomainMembersJob".
 
143
        for ( int i = 0; i < subjobs().size(); ++i )
 
144
        {
 
145
          if ( subjobs().at( i )->objectName().startsWith( "LookupDomainMembersJob" ) )
 
146
          {
 
147
            running = true;
 
148
            break;
 
149
          }
 
150
          else
 
151
          {
 
152
            continue;
 
153
          }
 
154
        }
 
155
      }
 
156
      break;
 
157
    }
 
158
    case LookupShares:
 
159
    {
 
160
      if ( item && item->type() == Smb4KBasicNetworkItem::Host )
 
161
      {
 
162
        // Only return TRUE if a job for the passed host is running.
 
163
        Smb4KHost *host = static_cast<Smb4KHost *>( item );
 
164
        
 
165
        if ( host )
 
166
        {
 
167
          for ( int i = 0; i < subjobs().size(); ++i )
 
168
          {
 
169
            if ( QString::compare( subjobs().at( i )->objectName(),
 
170
                 QString( "LookupSharesJob_%1" ).arg( host->hostName() ), Qt::CaseInsensitive ) == 0 )
 
171
            {
 
172
              running = true;
 
173
              break;
 
174
            }
 
175
            else
 
176
            {
 
177
              continue;
 
178
            }
 
179
          }
 
180
        }
 
181
        else
 
182
        {
 
183
          // Do nothing --- This should not happen.
 
184
        }
 
185
      }
 
186
      else
 
187
      {
 
188
        // If no item is defined, we just loop through the subjobs
 
189
        // and search for a "LookupSharesJob".
 
190
        for ( int i = 0; i < subjobs().size(); ++i )
 
191
        {
 
192
          if ( subjobs().at( i )->objectName().startsWith( "LookupSharesJob" ) )
 
193
          {
 
194
            running = true;
 
195
            break;
 
196
          }
 
197
          else
 
198
          {
 
199
            continue;
 
200
          }
 
201
        }
 
202
      }
 
203
      break;
 
204
    }
 
205
    case LookupInfo:
 
206
    {
 
207
      if ( item && item->type() == Smb4KBasicNetworkItem::Host )
 
208
      {
 
209
        // Only return TRUE if a job for the passed host is running.
 
210
        Smb4KHost *host = static_cast<Smb4KHost *>( item );
 
211
        
 
212
        if ( host )
 
213
        {
 
214
          for ( int i = 0; i < subjobs().size(); ++i )
 
215
          {
 
216
            if ( QString::compare( subjobs().at( i )->objectName(),
 
217
                 QString( "LookupInfoJob_%1" ).arg( host->hostName() ), Qt::CaseInsensitive ) == 0 )
 
218
            {
 
219
              running = true;
 
220
              break;
 
221
            }
 
222
            else
 
223
            {
 
224
              continue;
 
225
            }
 
226
          }
 
227
        }
 
228
        else
 
229
        {
 
230
          // Do nothing --- This should not happen.
 
231
        }
 
232
      }
 
233
      else
 
234
      {
 
235
        // If no item is defined, we just loop through the subjobs
 
236
        // and search for a "LookupInfoJob".
 
237
        for ( int i = 0; i < subjobs().size(); ++i )
 
238
        {
 
239
          if ( subjobs().at( i )->objectName().startsWith( "LookupInfoJob" ) )
 
240
          {
 
241
            running = true;
 
242
            break;
 
243
          }
 
244
          else
 
245
          {
 
246
            continue;
 
247
          }
 
248
        }
 
249
      }
 
250
      break;
 
251
    }
 
252
    default:
 
253
    {
 
254
      break;
 
255
    }
 
256
  }
 
257
 
 
258
  return running;
 
259
}
 
260
 
 
261
 
 
262
void Smb4KScanner::abortAll()
 
263
{
 
264
  for ( int i = 0; i < subjobs().size(); ++i )
 
265
  {
 
266
    subjobs().at( i )->kill( KJob::EmitResult );
 
267
  }
 
268
}
 
269
 
 
270
 
 
271
void Smb4KScanner::abort( Smb4KScanner::Process process, Smb4KBasicNetworkItem *item )
 
272
{
 
273
  switch ( process )
 
274
  {
 
275
    case LookupDomains:
 
276
    {
 
277
      // We do not need a network item with this kind
 
278
      // of process. We'll just kill all jobs labeled
 
279
      // 'LookupDomainsJob' and 'ScanBAreasJob'.
 
280
      for ( int i = 0; i < subjobs().size(); ++i )
 
281
      {
 
282
        if ( QString::compare( subjobs().at( i )->objectName(), "LookupDomainsJob" ) == 0 ||
 
283
             QString::compare( subjobs().at( i )->objectName(), "ScanBAreasJob" ) == 0 )
 
284
        {
 
285
          subjobs().at( i )->kill( KJob::EmitResult );
 
286
          continue;
 
287
        }
 
288
        else
 
289
        {
 
290
          continue;
 
291
        }
 
292
      }
 
293
      break;
 
294
    }
 
295
    case LookupDomainMembers:
 
296
    {
 
297
      if ( item && item->type() == Smb4KBasicNetworkItem::Workgroup )
 
298
      {
 
299
        // Only kill a job if the workgroup matches.
 
300
        Smb4KWorkgroup *workgroup = static_cast<Smb4KWorkgroup *>( item );
 
301
        
 
302
        if ( workgroup )
 
303
        {
 
304
          for ( int i = 0; i < subjobs().size(); ++i )
 
305
          {
 
306
            if ( QString::compare( subjobs().at( i )->objectName(),
 
307
                 QString( "LookupDomainMembersJob_%1" ).arg( workgroup->workgroupName() ), Qt::CaseInsensitive ) == 0 )
 
308
            {
 
309
              subjobs().at( i )->kill( KJob::EmitResult );
 
310
              break;
 
311
            }
 
312
            else
 
313
            {
 
314
              continue;
 
315
            }
 
316
          }
 
317
        }
 
318
        else
 
319
        {
 
320
          // Do nothing --- This should not happen.
 
321
        }
 
322
      }
 
323
      else
 
324
      {
 
325
        // If no item is defined, we just loop through the subjobs
 
326
        // and search for a "LookupDomainMembersJob".
 
327
        for ( int i = 0; i < subjobs().size(); ++i )
 
328
        {
 
329
          if ( subjobs().at( i )->objectName().startsWith( "LookupDomainMembersJob" ) )
 
330
          {
 
331
            subjobs().at( i )->kill( KJob::EmitResult );
 
332
            continue;
 
333
          }
 
334
          else
 
335
          {
 
336
            continue;
 
337
          }
 
338
        }
 
339
      }
 
340
      break;
 
341
    }
 
342
    case LookupShares:
 
343
    {
 
344
      if ( item && item->type() == Smb4KBasicNetworkItem::Host )
 
345
      {
 
346
        // Only kill a job if the host matches
 
347
        Smb4KHost *host = static_cast<Smb4KHost *>( item );
 
348
        
 
349
        if ( host )
 
350
        {
 
351
          for ( int i = 0; i < subjobs().size(); ++i )
 
352
          {
 
353
            if ( QString::compare( subjobs().at( i )->objectName(),
 
354
                 QString( "LookupSharesJob_%1" ).arg( host->hostName() ), Qt::CaseInsensitive ) == 0 )
 
355
            {
 
356
              subjobs().at( i )->kill( KJob::EmitResult );
 
357
              break;
 
358
            }
 
359
            else
 
360
            {
 
361
              continue;
 
362
            }
 
363
          }
 
364
        }
 
365
        else
 
366
        {
 
367
          // Do nothing --- This should not happen.
 
368
        }
 
369
      }
 
370
      else
 
371
      {
 
372
        // If no item is defined, we just loop through the subjobs
 
373
        // and search for a "LookupSharesJob".
 
374
        for ( int i = 0; i < subjobs().size(); ++i )
 
375
        {
 
376
          if ( subjobs().at( i )->objectName().startsWith( "LookupSharesJob" ) )
 
377
          {
 
378
            subjobs().at( i )->kill( KJob::EmitResult );
 
379
            continue;
 
380
          }
 
381
          else
 
382
          {
 
383
            continue;
 
384
          }
 
385
        }
 
386
      }
 
387
 
 
388
      break;
 
389
    }
 
390
    case LookupInfo:
 
391
    {
 
392
      if ( item && item->type() == Smb4KBasicNetworkItem::Host )
 
393
      {
 
394
        // Only return TRUE if a job for the passed host is running.
 
395
        Smb4KHost *host = static_cast<Smb4KHost *>( item );
 
396
        
 
397
        if ( host )
 
398
        {
 
399
          for ( int i = 0; i < subjobs().size(); ++i )
 
400
          {
 
401
            if ( QString::compare( subjobs().at( i )->objectName(),
 
402
                 QString( "LookupInfoJob_%1" ).arg( host->hostName() ), Qt::CaseInsensitive ) == 0 )
 
403
            {
 
404
              subjobs().at( i )->kill( KJob::EmitResult );
 
405
              break;
 
406
            }
 
407
            else
 
408
            {
 
409
              continue;
 
410
            }
 
411
          }
 
412
        }
 
413
        else
 
414
        {
 
415
          // Do nothing --- This should not happen.
 
416
        }
 
417
      }
 
418
      else
 
419
      {
 
420
        // If no item is defined, we just loop through the subjobs
 
421
        // and search for a "LookupInfoJob".
 
422
        for ( int i = 0; i < subjobs().size(); ++i )
 
423
        {
 
424
          if ( subjobs().at( i )->objectName().startsWith( "LookupInfoJob" ) )
 
425
          {
 
426
            subjobs().at( i )->kill( KJob::EmitResult );
 
427
            continue;
 
428
          }
 
429
          else
 
430
          {
 
431
            continue;
 
432
          }
 
433
        }
 
434
      }
 
435
      break;
 
436
    }
 
437
    default:
 
438
    {
 
439
      break;
 
440
    }
 
441
  }
 
442
}
 
443
 
 
444
 
 
445
void Smb4KScanner::start()
 
446
{
 
447
  // Avoid a race with QApplication and use 50 ms here.
 
448
  QTimer::singleShot( 50, this, SLOT( slotStartJobs() ) );
 
449
}
 
450
 
 
451
 
 
452
void Smb4KScanner::lookupDomains( QWidget *parent )
 
453
{
 
454
  if ( Smb4KSettings::lookupDomains() )
 
455
  {
 
456
    Smb4KLookupDomainsJob *job = new Smb4KLookupDomainsJob( this );
 
457
    job->setObjectName( "LookupDomainsJob" );
 
458
    job->setupLookup( parent );
 
459
 
 
460
    connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
461
    connect( job, SIGNAL( aboutToStart() ), SLOT( slotAboutToStartDomainsLookup() ) );
 
462
    connect( job, SIGNAL( finished() ), SLOT( slotDomainsLookupFinished() ) );
 
463
    connect( job, SIGNAL( workgroups( const QList<Smb4KWorkgroup> & ) ), SLOT( slotWorkgroups( const QList<Smb4KWorkgroup> & ) ) );
 
464
 
 
465
    if ( !hasSubjobs() )
 
466
    {
 
467
      QApplication::setOverrideCursor( Qt::BusyCursor );
 
468
    }
 
469
    else
 
470
    {
 
471
      // Do nothing
 
472
    }
 
473
 
 
474
    addSubjob( job );
 
475
 
 
476
    job->start();
 
477
  }
 
478
  else if ( Smb4KSettings::queryCurrentMaster() )
 
479
  {
 
480
    Smb4KQueryMasterJob *job = new Smb4KQueryMasterJob( this );
 
481
    job->setObjectName( "LookupDomainsJob" );
 
482
    job->setupLookup( QString(), parent );
 
483
 
 
484
    connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
485
    connect( job, SIGNAL( aboutToStart() ), SLOT( slotAboutToStartDomainsLookup() ) );
 
486
    connect( job, SIGNAL( finished() ), SLOT( slotDomainsLookupFinished() ) );
 
487
    connect( job, SIGNAL( workgroups( const QList<Smb4KWorkgroup> & ) ), SLOT( slotWorkgroups( const QList<Smb4KWorkgroup> & ) ) );
 
488
    connect( job, SIGNAL( authError( Smb4KQueryMasterJob * ) ), SLOT( slotAuthError( Smb4KQueryMasterJob * ) ) );
 
489
 
 
490
    if ( !hasSubjobs() )
 
491
    {
 
492
      QApplication::setOverrideCursor( Qt::BusyCursor );
 
493
    }
 
494
    else
 
495
    {
 
496
      // Do nothing
 
497
    }
 
498
 
 
499
    addSubjob( job );
 
500
 
 
501
    job->start();
 
502
  }
 
503
  else if ( Smb4KSettings::queryCustomMaster() )
 
504
  {
 
505
    // If the custom master browser entry is empty, warn the user
 
506
    // and tell him/her that we are going to query the current master
 
507
    // browser instead.
 
508
    if ( Smb4KSettings::customMasterBrowser().isEmpty() )
 
509
    {
 
510
      Smb4KNotification *notification = new Smb4KNotification();
 
511
      notification->emptyCustomMasterBrowser();
 
512
    }
 
513
    else
 
514
    {
 
515
      // Do nothing
 
516
    }
 
517
    
 
518
    Smb4KQueryMasterJob *job = new Smb4KQueryMasterJob( this );
 
519
    job->setObjectName( "LookupDomainsJob" );
 
520
    job->setupLookup( Smb4KSettings::customMasterBrowser(), parent );
 
521
 
 
522
    connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
523
    connect( job, SIGNAL( aboutToStart() ), SLOT( slotAboutToStartDomainsLookup() ) );
 
524
    connect( job, SIGNAL( finished() ), SLOT( slotDomainsLookupFinished() ) );
 
525
    connect( job, SIGNAL( workgroups( const QList<Smb4KWorkgroup> & ) ), SLOT( slotWorkgroups( const QList<Smb4KWorkgroup> & ) ) );
 
526
    connect( job, SIGNAL( authError( Smb4KQueryMasterJob * ) ), SLOT( slotAuthError( Smb4KQueryMasterJob * ) ) );
 
527
 
 
528
    if ( !hasSubjobs() )
 
529
    {
 
530
      QApplication::setOverrideCursor( Qt::BusyCursor );
 
531
    }
 
532
    else
 
533
    {
 
534
      // Do nothing
 
535
    }
 
536
 
 
537
    addSubjob( job );
 
538
 
 
539
    job->start();
 
540
  }
 
541
  else if ( Smb4KSettings::scanBroadcastAreas() )
 
542
  {
 
543
    if ( !Smb4KSettings::broadcastAreas().isEmpty() )
 
544
    {
 
545
      Smb4KScanBAreasJob *job = new Smb4KScanBAreasJob( this );
 
546
      job->setObjectName( "ScanBAreasJob" );
 
547
      job->setupScan( parent );
 
548
 
 
549
      connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
550
      connect( job, SIGNAL( aboutToStart() ), SLOT( slotAboutToStartDomainsLookup() ) );
 
551
      connect( job, SIGNAL( finished() ), SLOT( slotDomainsLookupFinished() ) );
 
552
      connect( job, SIGNAL( workgroups( const QList<Smb4KWorkgroup> & ) ), SLOT( slotWorkgroups( const QList<Smb4KWorkgroup> & ) ) );
 
553
      connect( job, SIGNAL( hosts( const QList<Smb4KHost> & ) ), SLOT( slotHosts( const QList<Smb4KHost> & ) ) );
 
554
 
 
555
      if ( !hasSubjobs() )
 
556
      {
 
557
        QApplication::setOverrideCursor( Qt::BusyCursor );
 
558
      }
 
559
      else
 
560
      {
 
561
        // Do nothing
 
562
      }
 
563
 
 
564
      addSubjob( job );
 
565
 
 
566
      job->start();
 
567
    }
 
568
    else
 
569
    {
 
570
      Smb4KNotification *notification = new Smb4KNotification();
 
571
      notification->emptyBroadcastAreas();
 
572
    }
 
573
  }
 
574
  else
 
575
  {
 
576
    // Do nothing
 
577
  }
 
578
}
 
579
 
 
580
 
 
581
void Smb4KScanner::lookupDomainMembers( Smb4KWorkgroup *workgroup, QWidget *parent )
 
582
{
 
583
  Q_ASSERT( workgroup );
 
584
 
 
585
  Smb4KLookupDomainMembersJob *job = new Smb4KLookupDomainMembersJob( this );
 
586
  job->setObjectName( QString( "LookupDomainMembersJob_%1" ).arg( workgroup->workgroupName() ) );
 
587
  job->setupLookup( workgroup, parent );
 
588
 
 
589
  connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
590
  connect( job, SIGNAL( aboutToStart( Smb4KWorkgroup * ) ), SLOT( slotAboutToStartHostsLookup( Smb4KWorkgroup * ) ) );
 
591
  connect( job, SIGNAL( finished( Smb4KWorkgroup * ) ), SLOT( slotHostsLookupFinished( Smb4KWorkgroup * ) ) );
 
592
  connect( job, SIGNAL( hosts( Smb4KWorkgroup *, const QList<Smb4KHost> & ) ), SLOT( slotHosts( Smb4KWorkgroup *, const QList<Smb4KHost> & ) ) );
 
593
  connect( job, SIGNAL( authError( Smb4KLookupDomainMembersJob * ) ), SLOT( slotAuthError( Smb4KLookupDomainMembersJob * ) ) );
 
594
 
 
595
  if ( !hasSubjobs() )
 
596
  {
 
597
    QApplication::setOverrideCursor( Qt::BusyCursor );
 
598
  }
 
599
  else
 
600
  {
 
601
    // Do nothing
 
602
  }
 
603
 
 
604
  addSubjob( job );
 
605
 
 
606
  job->start();
 
607
}
 
608
 
 
609
 
 
610
void Smb4KScanner::lookupShares( Smb4KHost *host, QWidget *parent )
 
611
{
 
612
  Q_ASSERT( host );
 
613
  
 
614
  Smb4KLookupSharesJob *job = new Smb4KLookupSharesJob( this );
 
615
  job->setObjectName( QString( "LookupSharesJob_%1" ).arg( host->hostName() ) );
 
616
  job->setupLookup( host, parent );
 
617
  
 
618
  connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
619
  connect( job, SIGNAL( aboutToStart( Smb4KHost * ) ), SLOT( slotAboutToStartSharesLookup( Smb4KHost * ) ) );
 
620
  connect( job, SIGNAL( finished( Smb4KHost * ) ), SLOT( slotSharesLookupFinished( Smb4KHost * ) ) );
 
621
  connect( job, SIGNAL( shares( Smb4KHost *, const QList<Smb4KShare> & ) ), SLOT( slotShares( Smb4KHost *, const QList<Smb4KShare> &) ) );
 
622
  connect( job, SIGNAL( authError( Smb4KLookupSharesJob * ) ), SLOT( slotAuthError( Smb4KLookupSharesJob * ) ) );
 
623
  
 
624
  if ( !hasSubjobs() )
 
625
  {
 
626
    QApplication::setOverrideCursor( Qt::BusyCursor );
 
627
  }
 
628
  else
 
629
  {
 
630
    // Do nothing
 
631
  }
 
632
 
 
633
  addSubjob( job );
 
634
 
 
635
  job->start();
 
636
}
 
637
 
 
638
 
 
639
void Smb4KScanner::lookupInfo( Smb4KHost *host, QWidget *parent )
 
640
{
 
641
  Q_ASSERT( host );
 
642
  
 
643
  // Check if the additional information (Server, OS) has already been
 
644
  // aquired previously or if we need to start a lookup job.
 
645
  Smb4KHost *known_host = findHost( host->hostName(), host->workgroupName() );
 
646
  
138
647
  if ( known_host && known_host->infoChecked() )
139
648
  {
140
649
    emit info( known_host );
141
 
 
142
 
    return;
143
 
  }
144
 
  else
145
 
  {
146
 
    // Don't let Smb4K check this host several times. This will
147
 
    // be reset in processInfo() if necessary.
148
 
    host->setInfo( QString(), QString() );
149
 
  }
150
 
 
151
 
  m_queue.enqueue( QueueContainer( Info, *host ) );
152
 
}
153
 
 
154
 
 
155
 
void Smb4KScanner::lookupDomains()
156
 
{
157
 
  // Abort any process that is still running.
158
 
  abort();
159
 
 
160
 
  // Assemble the command.
161
 
  QString command;
162
 
 
163
 
  command.append( "nmblookup -M " );
164
 
  command.append( Smb4KSambaOptionsHandler::self()->nmblookupOptions() );
165
 
  command.append( " -- - | grep '<01>' | awk '{print $1}'" );
166
 
  command.append( !Smb4KSambaOptionsHandler::self()->winsServer().isEmpty() ?
167
 
                  QString( " | xargs -Iips nmblookup -R -U %1 -A ips" ).arg( Smb4KSambaOptionsHandler::self()->winsServer() ) :
168
 
                  " | xargs -Iips nmblookup -A ips" );
169
 
  command.append( Smb4KSambaOptionsHandler::self()->nmblookupOptions() );
170
 
 
171
 
  m_proc->setShellCommand( command );
172
 
 
173
 
  startProcess( Workgroups );
174
 
}
175
 
 
176
 
 
177
 
void Smb4KScanner::queryMasterBrowser()
178
 
{
179
 
  // Abort any process that is still running.
180
 
  abort();
181
 
 
182
 
  // Assemble the command.
183
 
  QString command;
184
 
 
185
 
  command.append( "net " );
186
 
 
187
 
  if ( Smb4KSettings::queryCurrentMaster() )
188
 
  {
189
 
    Smb4KWorkgroup workgroup( Smb4KSettings::domainName() );
190
 
 
191
 
    command.append( Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::LookupMaster, workgroup ) );
192
 
    command.append( " -U % | xargs -Imaster net " );
193
 
    command.append( Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::Domain ) );
194
 
    command.append( " -U % -S master" );
195
 
  }
196
 
  else if ( Smb4KSettings::queryCustomMaster() )
197
 
  {
198
 
    Smb4KHost host( Smb4KSettings::customMasterBrowser() );
199
 
 
200
 
    command.append( Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::LookupHost, host ) );
201
 
    command.append( " -U % -S "+KShell::quoteArg( host.name() ) );
202
 
    command.append( " | xargs -Iip net " );
203
 
    command.append( Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::Domain ) );
204
 
    command.append( " -U % -S "+KShell::quoteArg( host.name() )+" -I ip" );
205
 
  }
206
 
  else
207
 
  {
208
 
    return;
209
 
  }
210
 
 
211
 
  m_proc->setShellCommand( command );
212
 
 
213
 
  startProcess( QueryHost );
214
 
}
215
 
 
216
 
 
217
 
void Smb4KScanner::scanBroadcastAreas()
218
 
{
219
 
  // Abort any process that is still running.
220
 
  abort();
221
 
 
222
 
  // Assemble the command.
223
 
  QString command;
224
 
 
225
 
  // Get the broadcast addresses that are to be scanned:
226
 
  QStringList addresses = Smb4KSettings::broadcastAreas().split( ",", QString::SkipEmptyParts );
227
 
 
228
 
  // Build the command:
229
 
  for ( int i = 0; i < addresses.size(); ++i )
230
 
  {
231
 
    command.append( "nmblookup " );
232
 
    // We want all globally defined options for nmblookup, except
233
 
    // the broadcast address, because that is needed for the IP
234
 
    // scan:
235
 
    command.append( Smb4KSambaOptionsHandler::self()->nmblookupOptions( false ) );
236
 
    command.append( " -B "+addresses.at( i )+" -- '*' " );
237
 
    command.append( "| sed -e /querying/d | awk '{print $1}' " );
238
 
    command.append( "| xargs -Iip nmblookup " );
239
 
    // This time we want to have the globally defined broadcast
240
 
    // address:
241
 
    command.append( Smb4KSambaOptionsHandler::self()->nmblookupOptions() );
242
 
    // Include the WINS server:
243
 
    command.append( !Smb4KSambaOptionsHandler::self()->winsServer().isEmpty() ?
244
 
                    " -R -U "+Smb4KSambaOptionsHandler::self()->winsServer()+" " : "" );
245
 
    command.append( " -A ip" );
246
 
    command.append( " ; " );
247
 
  }
248
 
 
249
 
  // Get rid of the last 3 characters (" ; "):
250
 
  command.truncate( command.length() - 3 );
251
 
 
252
 
  m_proc->setShellCommand( command );
253
 
 
254
 
  startProcess( IPScan );
255
 
}
256
 
 
257
 
 
258
 
void Smb4KScanner::scanForWorkgroupMembers( const Smb4KWorkgroup &workgroup )
259
 
{
260
 
  m_priv->setWorkgroup( workgroup );
261
 
 
262
 
  QString command;
263
 
 
264
 
  if ( !workgroup.masterBrowserIP().isEmpty() )
265
 
  {
266
 
    command.append( "net "+Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::ServerDomain ) );
267
 
    command.append( " -I "+workgroup.masterBrowserIP() );
268
 
    command.append( " -w "+KShell::quoteArg( workgroup.name() ) );
269
 
    command.append( " -S "+KShell::quoteArg( workgroup.masterBrowserName() ) );
270
 
 
271
 
    if ( Smb4KSettings::masterBrowsersRequireAuth() )
272
 
    {
273
 
      // Find the master browser and read the authentication information
274
 
      // for it.
275
 
      Smb4KHost *master = findHost( workgroup.masterBrowserName(), workgroup.name() );
276
 
      Smb4KAuthInfo authInfo;
277
 
      
278
 
      if ( master )
279
 
      {
280
 
        authInfo = Smb4KAuthInfo( master );
281
 
        Smb4KWalletManager::self()->readAuthInfo( &authInfo );
282
 
      }
283
 
      else
284
 
      {
285
 
        // Do nothing
286
 
      }
287
 
 
288
 
      if ( !authInfo.login().isEmpty() )
289
 
      {
290
 
        command.append( QString( " -U %1" ).arg( KShell::quoteArg( authInfo.login() ) ) );
291
 
 
292
 
        if ( !authInfo.password().isEmpty() )
293
 
        {
294
 
          m_proc->setEnv( "PASSWD", authInfo.password() );
295
 
        }
296
 
        else
297
 
        {
298
 
          // Do nothing
299
 
        }
300
 
      }
301
 
      else
302
 
      {
303
 
        command.append( " -U %" );
304
 
      }
305
 
    }
306
 
    else
307
 
    {
308
 
      command.append( " -U %" );
309
 
    }
310
 
  }
311
 
  else
312
 
  {
313
 
    command.append( "net "+Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::LookupHost, workgroup ) );
314
 
    command.append( " -S "+KShell::quoteArg( workgroup.masterBrowserName() ) );
315
 
    command.append( " -w "+KShell::quoteArg( workgroup.name() ) );
316
 
    command.append( " -U % " );
317
 
    // FIXME: Maybe we need to know the shell if the user does not use a
318
 
    // sh-compatible one...?
319
 
    command.append( "| xargs -Iip " );
320
 
    command.append( getenv( "SHELL" ) );
321
 
    command.append( " -c 'echo \"*** "+workgroup.masterBrowserName()+": ip ***\" && " );
322
 
    command.append( "net "+Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::ServerDomain ) );
323
 
    command.append( " -I ip" );
324
 
    command.append( " -w "+KShell::quoteArg( workgroup.name() ) );
325
 
    command.append( " -S "+KShell::quoteArg( workgroup.masterBrowserName() ) );
326
 
 
327
 
    if ( Smb4KSettings::masterBrowsersRequireAuth() )
328
 
    {
329
 
      Smb4KHost *master = findHost( workgroup.masterBrowserName(), workgroup.name() );
330
 
      Smb4KAuthInfo authInfo;
331
 
      
332
 
      if ( master )
333
 
      {
334
 
        authInfo = Smb4KAuthInfo( master );
335
 
        Smb4KWalletManager::self()->readAuthInfo( &authInfo );
336
 
      }
337
 
      else
338
 
      {
339
 
        // Do nothing
340
 
      }
341
 
 
342
 
      if ( !authInfo.login().isEmpty() )
343
 
      {
344
 
        command.append( QString( " -U %1'" ).arg( KShell::quoteArg( authInfo.login() ) ) );
345
 
 
346
 
        if ( !authInfo.password().isEmpty() )
347
 
        {
348
 
          m_proc->setEnv( "PASSWD", authInfo.password() );
349
 
        }
350
 
        else
351
 
        {
352
 
          // Do nothing
353
 
        }
354
 
      }
355
 
      else
356
 
      {
357
 
        command.append( " -U %'" );
358
 
      }
359
 
    }
360
 
    else
361
 
    {
362
 
      command.append( " -U %'" );
363
 
    }
364
 
  }
365
 
 
366
 
  m_proc->setShellCommand( command );
367
 
 
368
 
  startProcess( Hosts );
369
 
}
370
 
 
371
 
 
372
 
void Smb4KScanner::scanForShares( const Smb4KHost &host )
373
 
{
374
 
  m_priv->setHost( host );
375
 
 
376
 
  Smb4KAuthInfo authInfo( &host );
377
 
  Smb4KWalletManager::self()->readAuthInfo( &authInfo );
378
 
 
379
 
  QString command;
380
 
 
381
 
  command.append( "net "+Smb4KSambaOptionsHandler::self()->netOptions( Smb4KSambaOptionsHandler::Share, host ) );
382
 
  command.append( " -w "+KShell::quoteArg( host.workgroup() ) );
383
 
  command.append( " -S "+KShell::quoteArg( host.name() ) );
384
 
 
385
 
  if ( !host.ip().isEmpty() )
386
 
  {
387
 
    command.append( QString( " -I %1" ).arg( KShell::quoteArg( host.ip() ) ) );
388
 
  }
389
 
 
390
 
  if ( !authInfo.login().isEmpty() )
391
 
  {
392
 
    command.append( QString( " -U %1" ).arg( KShell::quoteArg( authInfo.login() ) ) );
393
 
 
394
 
    if ( !authInfo.password().isEmpty() )
395
 
    {
396
 
      m_proc->setEnv( "PASSWD", authInfo.password() );
397
 
    }
398
 
  }
399
 
  else
400
 
  {
401
 
    command.append( " -U guest%" );
402
 
  }
403
 
 
404
 
  m_proc->setShellCommand( command );
405
 
 
406
 
  startProcess( Shares );
407
 
}
408
 
 
409
 
 
410
 
void Smb4KScanner::scanForInfo( const Smb4KHost &host )
411
 
{
412
 
  m_priv->setHost( host );
413
 
 
414
 
  QString smbclient_options = Smb4KSambaOptionsHandler::self()->smbclientOptions();
415
 
 
416
 
  QString command;
417
 
  command.append( "smbclient -d1 -U guest%" );
418
 
  command.append( " -W "+KShell::quoteArg( host.workgroup() ) );
419
 
  command.append( " -L "+KShell::quoteArg( host.name() ) );
420
 
 
421
 
  if ( !host.ip().isEmpty() )
422
 
  {
423
 
    command.append( " -I "+KShell::quoteArg( host.ip() ) );
424
 
  }
425
 
 
426
 
  if ( !smbclient_options.trimmed().isEmpty() )
427
 
  {
428
 
    command.append( smbclient_options );
429
 
  }
430
 
 
431
 
  m_proc->setShellCommand( command );
432
 
 
433
 
  startProcess( Info );
434
 
}
435
 
 
436
 
 
437
 
void Smb4KScanner::startProcess( int state )
438
 
{
439
 
  m_aborted = false;
440
 
 
441
 
  m_state = state;
442
 
 
443
 
  if ( state != Info )
444
 
  {
445
 
    QApplication::setOverrideCursor( Qt::WaitCursor );
446
 
  }
447
 
 
448
 
  m_proc->setOutputChannelMode( KProcess::SeparateChannels );
449
 
  m_proc->start();
450
 
}
451
 
 
452
 
 
453
 
void Smb4KScanner::endProcess( int /*exitCode*/, QProcess::ExitStatus exitStatus )
454
 
{
455
 
  if ( exitStatus == QProcess::NormalExit )
456
 
  {
457
 
    switch ( m_state )
458
 
    {
459
 
      case Workgroups:
460
 
      case QueryHost:
461
 
      {
462
 
        processWorkgroups();
463
 
        break;
464
 
      }
465
 
      case IPScan:
466
 
      {
467
 
        processIPScan();
468
 
        break;
469
 
      }
470
 
      case Hosts:
471
 
      {
472
 
        processWorkgroupMembers();
473
 
        break;
474
 
      }
475
 
      case Shares:
476
 
      {
477
 
        processShares();
478
 
        break;
479
 
      }
480
 
      case Info:
481
 
      {
482
 
        processInfo( exitStatus );
483
 
        break;
484
 
      }
485
 
      default:
486
 
      {
487
 
        break;
488
 
      }
489
 
    }
490
 
  }
491
 
  else
492
 
  {
493
 
    // In case we searched for information, invoke processInfo(),
494
 
    // since the host needs to be resetted.
495
 
    switch ( m_state )
496
 
    {
497
 
      case Info:
498
 
      {
499
 
        processInfo( exitStatus );
500
 
        break;
501
 
      }
502
 
      default:
503
 
      {
504
 
        break;
505
 
      }
506
 
    }
507
 
 
508
 
    // Something went wrong. Throw an error if the problem was not
509
 
    // caused by using the abort() function.
510
 
    if ( !m_aborted )
511
 
    {
512
 
      if ( m_process_error != -1 )
513
 
      {
514
 
        Smb4KCoreMessage::processError( ERROR_PROCESS_ERROR, m_process_error );
515
 
      }
516
 
      else
517
 
      {
518
 
        Smb4KCoreMessage::processError( ERROR_PROCESS_EXIT, m_process_error );
519
 
      }
520
 
 
521
 
      emit failed();
522
 
    }
523
 
    else
524
 
    {
525
 
      // Do nothing
526
 
    }
527
 
  }
528
 
 
529
 
  m_state = Idle;
530
 
 
531
 
  m_priv->clearData();
532
 
 
533
 
  QApplication::restoreOverrideCursor();
534
 
  m_proc->clearProgram();
535
 
 
536
 
  m_process_error = (QProcess::ProcessError)(-1);
537
 
  m_working = false;
538
 
 
539
 
  emit state( SCANNER_STOP );
540
 
}
541
 
 
542
 
 
543
 
void Smb4KScanner::processWorkgroups()
544
 
{
545
 
  // Read from stderr and decide what to do:
546
 
  QString stderr_output = QString::fromLocal8Bit( m_proc->readAllStandardError(), -1 ).trimmed();
547
 
 
548
 
  if ( !stderr_output.isEmpty() )
549
 
  {
550
 
    emit failed();
551
 
 
552
 
    Smb4KCoreMessage::error( ERROR_GETTING_WORKGROUPS, QString(), stderr_output );
553
 
 
554
 
    // Emit these signals so that the browser can be cleared.
555
 
    emit workgroups( *Smb4KGlobal::workgroupsList() );
556
 
    emit hostListChanged();
557
 
 
558
 
    return;
559
 
  }
560
 
 
561
 
  // There was no error. We can proceed with processing the
562
 
  // output from stdout.
563
 
  QString stdout_output = QString::fromLocal8Bit( m_proc->readAllStandardOutput(), -1 ).trimmed();
564
 
  QStringList list = stdout_output.split( "\n", QString::KeepEmptyParts );
565
 
 
566
 
  QList<Smb4KWorkgroup *> temp_workgroups_list;
567
 
 
568
 
  switch ( m_state )
569
 
  {
570
 
    case Workgroups:
571
 
    {
572
 
      Smb4KWorkgroup temp_workgroup;
573
 
      Smb4KHost temp_host;
574
 
 
575
 
      for ( int i = 0; i < list.size(); ++i )
576
 
      {
577
 
        if ( list.at( i ).startsWith( "Looking up status of" ) )
578
 
        {
579
 
          // Get the IP address of the host.
580
 
          temp_host.setIP( list.at( i ).section( "of", 1, 1 ).trimmed() );
581
 
 
582
 
          continue;
583
 
        }
584
 
        else if ( list.at( i ).contains( "MAC Address", Qt::CaseSensitive ) )
585
 
        {
586
 
          // Add workgroup and host to global lists.
587
 
          if ( !temp_workgroup.masterBrowserName().trimmed().isEmpty() )
588
 
          {
589
 
            Smb4KWorkgroup *workgroup = findWorkgroup( temp_workgroup.name() );
590
 
 
591
 
            if ( workgroup )
592
 
            {
593
 
              // Check if the master browser changed, get the old one (if necessary)
594
 
              // and reset it.
595
 
              if ( QString::compare( temp_workgroup.masterBrowserName(),
596
 
                   workgroup->masterBrowserName(), Qt::CaseInsensitive ) != 0 )
597
 
              {
598
 
                Smb4KHost *old_master_browser = findHost( workgroup->masterBrowserName(), workgroup->name() );
599
 
 
600
 
                if ( old_master_browser )
601
 
                {
602
 
                  old_master_browser->setIsMasterBrowser( false );
603
 
                }
604
 
                else
605
 
                {
606
 
                  // Do nothing
607
 
                }
608
 
              }
609
 
              else
610
 
              {
611
 
                // The old master browser is also the new one. The updating will be
612
 
                // done below.
613
 
              }
614
 
 
615
 
              // Update the workgroup.
616
 
              workgroup->setMasterBrowser( temp_workgroup.masterBrowserName(),
617
 
                                           temp_workgroup.masterBrowserIP(),
618
 
                                           false );
619
 
 
620
 
              // Put it into the temporary list...
621
 
              temp_workgroups_list.append( new Smb4KWorkgroup( *workgroup ) );
622
 
 
623
 
              // ... and remove it from the global one.
624
 
              int index = Smb4KGlobal::workgroupsList()->indexOf( workgroup );
625
 
              delete Smb4KGlobal::workgroupsList()->takeAt( index );
626
 
            }
627
 
            else
628
 
            {
629
 
              // Copy temporary workgroup and add it to the temporary list.
630
 
              temp_workgroups_list.append( new Smb4KWorkgroup( temp_workgroup ) );
631
 
            }
632
 
          }
633
 
          else
634
 
          {
635
 
            // Do nothing. The workgroup object has no master browser entry.
636
 
          }
637
 
 
638
 
          if ( !temp_host.isEmpty() )
639
 
          {
640
 
            Smb4KHost *host = findHost( temp_host.name(), temp_host.workgroup() );
641
 
 
642
 
            if ( host )
643
 
            {
644
 
              // Update the host.
645
 
              host->setIP( temp_host.ip() );
646
 
              host->setIsMasterBrowser( temp_host.isMasterBrowser() );
647
 
            }
648
 
            else
649
 
            {
650
 
              // Add the host.
651
 
              Smb4KGlobal::hostsList()->append( new Smb4KHost( temp_host ) );
652
 
            }
653
 
          }
654
 
 
655
 
          // Clear the temporary objects.
656
 
          temp_workgroup = Smb4KWorkgroup();
657
 
          temp_host      = Smb4KHost();
658
 
 
659
 
          continue;
660
 
        }
661
 
        else if ( list.at( i ).contains( " <00> ", Qt::CaseSensitive ) )
662
 
        {
663
 
          // Set the name of the workgroup/host.
664
 
          if ( list.at( i ).contains( " <GROUP> ", Qt::CaseSensitive ) )
665
 
          {
666
 
            temp_workgroup.setName( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
667
 
            temp_host.setWorkgroup( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
668
 
          }
669
 
          else
670
 
          {
671
 
            temp_host.setName( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
672
 
          }
673
 
 
674
 
          continue;
675
 
        }
676
 
        else if ( list.at( i ).contains( "__MSBROWSE__", Qt::CaseSensitive ) &&
677
 
                  list.at( i ).contains( " <01> ", Qt::CaseSensitive ) )
678
 
        {
679
 
          // The host is a master browser.
680
 
          temp_workgroup.setMasterBrowser( temp_host.name(), temp_host.ip(), false );
681
 
          temp_host.setIsMasterBrowser( true );
682
 
 
683
 
          continue;
684
 
        }
685
 
        else
686
 
        {
687
 
          continue;
688
 
        }
689
 
      }
690
 
 
691
 
      break;
692
 
    }
693
 
    case QueryHost:
694
 
    {
695
 
      Smb4KWorkgroup temp_workgroup;
696
 
      Smb4KHost temp_host;
697
 
 
698
 
      for ( int i = 0; i < list.size(); ++i )
699
 
      {
700
 
        if ( list.at( i ).trimmed().startsWith( "Enumerating" ) )
701
 
        {
702
 
          continue;
703
 
        }
704
 
        else if ( list.at( i ).trimmed().startsWith( "Domain name" ) )
705
 
        {
706
 
          continue;
707
 
        }
708
 
        else if ( list.at( i ).trimmed().startsWith( "-------------" ) )
709
 
        {
710
 
          continue;
711
 
        }
712
 
        else if ( list.at( i ).trimmed().isEmpty() )
713
 
        {
714
 
          continue;
715
 
        }
716
 
        else
717
 
        {
718
 
          // This is the workgroup and master entry. Process it.
719
 
          temp_workgroup.setName( list.at( i ).section( "   ", 0, 0 ).trimmed() );
720
 
          temp_workgroup.setMasterBrowserName( list.at( i ).section( "   ", 1, -1 ).trimmed() );
721
 
 
722
 
          temp_host.setName( temp_workgroup.masterBrowserName() );
723
 
          temp_host.setWorkgroup( temp_workgroup.name() );
724
 
          temp_host.setIsMasterBrowser( true );
725
 
 
726
 
          // Get the workgroup if it exists.
727
 
          Smb4KWorkgroup *workgroup = findWorkgroup( temp_workgroup.name() );
728
 
 
729
 
          if ( workgroup )
730
 
          {
731
 
            // Check if the master browser changed, get the old one (if necessary)
732
 
            // and reset it.
733
 
            if ( QString::compare( temp_workgroup.masterBrowserName(),
734
 
                 workgroup->masterBrowserName(), Qt::CaseInsensitive ) != 0 )
735
 
            {
736
 
              Smb4KHost *old_master_browser = findHost( workgroup->masterBrowserName(), workgroup->name() );
737
 
 
738
 
              if ( old_master_browser )
739
 
              {
740
 
                old_master_browser->setIsMasterBrowser( false );
741
 
              }
742
 
              else
743
 
              {
744
 
                // Do nothing
745
 
              }
746
 
            }
747
 
            else
748
 
            {
749
 
              // The old master browser is also the new one. The updating will be
750
 
              // done below.
751
 
            }
752
 
 
753
 
            // Update the workgroup.
754
 
            workgroup->setMasterBrowser( temp_workgroup.masterBrowserName(),
755
 
                                         QString(),
756
 
                                         false );
757
 
 
758
 
            // Put it into the temporary list...
759
 
            temp_workgroups_list.append( new Smb4KWorkgroup( *workgroup ) );
760
 
 
761
 
            // ... and remove it from the global one.
762
 
            int index = Smb4KGlobal::workgroupsList()->indexOf( workgroup );
763
 
            delete Smb4KGlobal::workgroupsList()->takeAt( index );
764
 
          }
765
 
          else
766
 
          {
767
 
            // Copy temporary workgroup and add it to the temporary list.
768
 
            temp_workgroups_list.append( new Smb4KWorkgroup( temp_workgroup ) );
769
 
          }
770
 
 
771
 
          // Search the new master browser in the global hosts list.
772
 
          Smb4KHost *host = findHost( temp_host.name(), temp_host.workgroup() );
773
 
 
774
 
          if ( host )
775
 
          {
776
 
            // Update the host.
777
 
            host->setIP( temp_host.ip() );
778
 
            host->setIsMasterBrowser( temp_host.isMasterBrowser() );
779
 
          }
780
 
          else
781
 
          {
782
 
            // Add the host.
783
 
            Smb4KGlobal::hostsList()->append( new Smb4KHost( temp_host ) );
784
 
          }
785
 
 
786
 
          // Clear the temporary objects.
787
 
          temp_workgroup = Smb4KWorkgroup();
788
 
          temp_host      = Smb4KHost();
789
 
 
790
 
          continue;
791
 
        }
792
 
      }
793
 
 
794
 
      break;
795
 
    }
796
 
    default:
797
 
    {
798
 
      break;
799
 
    }
800
 
  }
801
 
 
802
 
  // Clean up the internal hosts list. In Smb4KGlobal::workgroupsList()
803
 
  // only the obsolete workgroups are present. We use those to remove
804
 
  // all obsolete hosts.
805
 
  if ( !Smb4KGlobal::workgroupsList()->isEmpty() )
806
 
  {
807
 
    // Normally the list of obsolete workgroups is rather small.
808
 
    // Thus, we will loop through the host list and check the
809
 
    // workgroup.
810
 
    for ( int i = 0; i < Smb4KGlobal::hostsList()->size(); ++i )
811
 
    {
812
 
      Smb4KWorkgroup *workgroup = findWorkgroup( Smb4KGlobal::hostsList()->at( i )->workgroup() );
813
 
 
814
 
      if ( workgroup )
815
 
      {
816
 
        // The workgroup is obsolete. Remove the host.
817
 
        delete Smb4KGlobal::hostsList()->takeAt( i );
818
 
 
819
 
        continue;
820
 
      }
821
 
      else
822
 
      {
823
 
        // The workgroup is not obsolete.
824
 
        continue;
825
 
      }
826
 
    }
827
 
 
828
 
    // Clear the list of workgroups.
829
 
    while ( !Smb4KGlobal::workgroupsList()->isEmpty() )
830
 
    {
831
 
      delete Smb4KGlobal::workgroupsList()->takeFirst();
832
 
    }
833
 
  }
834
 
  else
835
 
  {
836
 
    // Do nothing
837
 
  }
838
 
 
839
 
  // Update the list of workgroups. We can append the new
840
 
  // list, because Smb4KGlobal::workgroupsList() is empty.
841
 
  *Smb4KGlobal::workgroupsList() += temp_workgroups_list;
842
 
 
843
 
  Smb4KIPAddressScanner::self()->triggerScan();
844
 
 
845
 
  emit workgroups( *Smb4KGlobal::workgroupsList() );
846
 
  emit hostListChanged();
847
 
}
848
 
 
849
 
 
850
 
void Smb4KScanner::processIPScan()
851
 
{
852
 
  // Read from stderr and decide what to do:
853
 
  QString stderr_output = QString::fromLocal8Bit( m_proc->readAllStandardError(), -1 ).trimmed();
854
 
 
855
 
  if ( !stderr_output.isEmpty() )
856
 
  {
857
 
    emit failed();
858
 
 
859
 
    Smb4KCoreMessage::error( ERROR_PERFORMING_IPSCAN, QString(), stderr_output );
860
 
 
861
 
    // Emit these signals so that the browser can be cleared.
862
 
    emit workgroups( *Smb4KGlobal::workgroupsList() );
863
 
    emit hostListChanged();
864
 
 
865
 
    return;
866
 
  }
867
 
 
868
 
  // There was no error. We can proceed with processing the
869
 
  // output from stdout.
870
 
  QString stdout_output = QString::fromLocal8Bit( m_proc->readAllStandardOutput(), -1 ).trimmed();
871
 
  QStringList list = stdout_output.split( "\n", QString::KeepEmptyParts );
872
 
 
873
 
  QList<Smb4KWorkgroup *> temp_workgroups_list;
874
 
  QList<Smb4KHost *> temp_hosts_list;
875
 
 
876
 
  // Process the data:
877
 
  Smb4KWorkgroup temp_workgroup;
878
 
  Smb4KHost temp_host;
879
 
 
880
 
  for ( int i = 0; i < list.size(); ++i )
881
 
  {
882
 
    if ( list.at( i ).startsWith( "Looking up status of" ) )
883
 
    {
884
 
      // Get the IP address of the host.
885
 
      temp_host.setIP( list.at( i ).section( "of", 1, 1 ).trimmed() );
886
 
 
887
 
      continue;
888
 
    }
889
 
    else if ( list.at( i ).contains( "MAC Address", Qt::CaseSensitive ) )
890
 
    {
891
 
      // Add workgroup and host to global lists.
892
 
      if ( !temp_workgroup.masterBrowserName().trimmed().isEmpty() )
893
 
      {
894
 
        Smb4KWorkgroup *workgroup = findWorkgroup( temp_workgroup.name() );
895
 
 
896
 
        if ( workgroup )
897
 
        {
898
 
          // Find out if we need to add it to the temporary list.
899
 
          bool found_workgroup = false;
900
 
 
901
 
          for ( int j = 0; j < temp_workgroups_list.size(); ++j )
902
 
          {
903
 
            if ( QString::compare( temp_workgroups_list.at( j )->name(), workgroup->name() ) == 0 )
904
 
            {
905
 
              found_workgroup = true;
906
 
 
907
 
              break;
908
 
            }
909
 
            else
910
 
            {
911
 
              continue;
912
 
            }
913
 
          }
914
 
 
915
 
          if ( !found_workgroup )
916
 
          {
917
 
            // Update the workgroup.
918
 
            workgroup->setMasterBrowser( temp_workgroup.masterBrowserName(),
919
 
                                         temp_workgroup.masterBrowserIP(),
920
 
                                         false );
921
 
 
922
 
            temp_workgroups_list.append( new Smb4KWorkgroup( *workgroup ) );
923
 
          }
924
 
          else
925
 
          {
926
 
            // Do nothing
927
 
          }
928
 
        }
929
 
        else
930
 
        {
931
 
          // Copy temporary workgroup and add it to the temporary list.
932
 
          temp_workgroups_list.append( new Smb4KWorkgroup( temp_workgroup ) );
933
 
        }
934
 
      }
935
 
      else
936
 
      {
937
 
        // Do nothing. The workgroup object has no master browser entry.
938
 
      }
939
 
 
940
 
      if ( !temp_host.isEmpty() )
941
 
      {
942
 
        Smb4KHost *host = findHost( temp_host.name(), temp_host.workgroup() );
943
 
 
944
 
        if ( host )
945
 
        {
946
 
          // Update the host.
947
 
          host->setIP( temp_host.ip() );
948
 
          host->setIsMasterBrowser( temp_host.isMasterBrowser() );
949
 
 
950
 
          temp_hosts_list.append( new Smb4KHost( *host ) );
951
 
        }
952
 
        else
953
 
        {
954
 
          temp_hosts_list.append( new Smb4KHost( temp_host ) );
955
 
        }
956
 
      }
957
 
 
958
 
      // Clear the temporary objects.
959
 
      temp_workgroup = Smb4KWorkgroup();
960
 
      temp_host      = Smb4KHost();
961
 
 
962
 
      continue;
963
 
    }
964
 
    else if ( list.at( i ).contains( " <00> ", Qt::CaseSensitive ) )
965
 
    {
966
 
      // Set the name of the workgroup/host.
967
 
      if ( list.at( i ).contains( " <GROUP> ", Qt::CaseSensitive ) )
968
 
      {
969
 
        temp_workgroup.setName( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
970
 
        temp_host.setWorkgroup( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
971
 
      }
972
 
      else
973
 
      {
974
 
        temp_host.setName( list.at( i ).section( "<00>", 0, 0 ).trimmed() );
975
 
      }
976
 
 
977
 
      continue;
978
 
    }
979
 
    else if ( list.at( i ).contains( "__MSBROWSE__", Qt::CaseSensitive ) &&
980
 
              list.at( i ).contains( " <01> ", Qt::CaseSensitive ) )
981
 
    {
982
 
      // The host is a master browser.
983
 
      temp_workgroup.setMasterBrowser( temp_host.name(), temp_host.ip(), false );
984
 
      temp_host.setIsMasterBrowser( true );
985
 
 
986
 
      continue;
987
 
    }
988
 
    else
989
 
    {
990
 
      continue;
991
 
    }
992
 
  }
993
 
 
994
 
  // No extra lookup of IP addresses is needed since
995
 
  // we searched for IP addresses.
996
 
 
997
 
  // Clear the internal list of workgroups and replace
998
 
  // it with the temporary one.
999
 
  while ( !Smb4KGlobal::workgroupsList()->isEmpty() )
1000
 
  {
1001
 
    delete Smb4KGlobal::workgroupsList()->takeFirst();
1002
 
  }
1003
 
 
1004
 
  *Smb4KGlobal::workgroupsList() += temp_workgroups_list;
1005
 
 
1006
 
  // Clear the internal list of hosts and replace it with
1007
 
  // the temporary one.
1008
 
  while ( !Smb4KGlobal::hostsList()->isEmpty() )
1009
 
  {
1010
 
    delete Smb4KGlobal::hostsList()->takeFirst();
1011
 
  }
1012
 
 
1013
 
  *Smb4KGlobal::hostsList() += temp_hosts_list;
1014
 
 
1015
 
  emit workgroups( *Smb4KGlobal::workgroupsList() );
1016
 
  emit hostListChanged();
1017
 
}
1018
 
 
1019
 
 
1020
 
void Smb4KScanner::processWorkgroupMembers()
1021
 
{
1022
 
  // Read from stderr and decide what to do:
1023
 
  QString stderr_output = QString::fromLocal8Bit( m_proc->readAllStandardError(), -1 ).trimmed();
1024
 
 
1025
 
  if ( !stderr_output.isEmpty() )
1026
 
  {
1027
 
    if ( Smb4KSettings::lookupDomains() ||
1028
 
         Smb4KSettings::queryCurrentMaster() ||
1029
 
         Smb4KSettings::queryCustomMaster() )
1030
 
    {
1031
 
      if ( stderr_output.contains( "The username or password was not correct." ) ||
1032
 
           stderr_output.contains( "NT_STATUS_ACCOUNT_DISABLED" ) /* AD error */ ||
1033
 
           stderr_output.contains( "NT_STATUS_ACCESS_DENIED" ) ||
1034
 
           stderr_output.contains( "NT_STATUS_LOGON_FAILURE" ) )
1035
 
      {
1036
 
        // Authentication failed.
1037
 
        emit failed();
1038
 
 
1039
 
        Smb4KAuthInfo authInfo( &m_priv->host() );
1040
 
 
1041
 
        if ( Smb4KWalletManager::self()->showPasswordDialog( &authInfo ) )
1042
 
        {
1043
 
          m_queue.enqueue( QueueContainer( Hosts, m_priv->host() ) );
1044
 
        }
1045
 
        else
1046
 
        {
1047
 
          // Do nothing
1048
 
        }
1049
 
      }
1050
 
      else
1051
 
      {
1052
 
        // Notify the rest of the program, that something went wrong.
1053
 
        emit failed();
1054
 
 
1055
 
        // Notify the user.
1056
 
        Smb4KCoreMessage::error( ERROR_GETTING_MEMBERS, QString(), stderr_output );
1057
 
      }
1058
 
    }
1059
 
    else if ( Smb4KSettings::scanBroadcastAreas() )
1060
 
    {
1061
 
      // We are in IP scan mode, so we can ignore the error and emit
1062
 
      // what we already have.
1063
 
      emit members( m_priv->workgroup().name(), *Smb4KGlobal::hostsList() );
1064
 
      emit hostListChanged();
1065
 
    }
1066
 
    else
1067
 
    {
1068
 
      // Do nothing
1069
 
    }
1070
 
 
1071
 
    return;
1072
 
  }
1073
 
 
1074
 
  // There was no error. We can proceed with processing the
1075
 
  // output from stdout.
1076
 
  QString stdout_output = QString::fromLocal8Bit( m_proc->readAllStandardOutput(), -1 ).trimmed();
1077
 
  QStringList list = stdout_output.split( "\n", QString::SkipEmptyParts );
1078
 
 
1079
 
  if ( Smb4KSettings::lookupDomains() ||
1080
 
       Smb4KSettings::queryCurrentMaster() ||
1081
 
       Smb4KSettings::queryCustomMaster() )
1082
 
  {
1083
 
    QList<Smb4KHost *> temp_hosts_list;
1084
 
    Smb4KHost temp_host;
1085
 
 
1086
 
    for ( int i = 0; i < list.size(); ++i )
1087
 
    {
1088
 
      if ( list.at( i ).startsWith( "***" ) && list.at( i ).endsWith( "***" ) )
1089
 
      {
1090
 
        // This is the IP address of the master browser. Add it
1091
 
        // to the respective workgroup, if necessary.
1092
 
        Smb4KWorkgroup *workgroup = findWorkgroup( m_priv->workgroup().name() );
1093
 
 
1094
 
        if ( workgroup && workgroup->masterBrowserIP().isEmpty() )
1095
 
        {
1096
 
          workgroup->setMasterBrowserIP( list.at( i ).section( ":", 1, 1 ).section( "***", 0, 0 ).trimmed() );
1097
 
        }
1098
 
        else
1099
 
        {
1100
 
          // Do nothing
1101
 
        }
1102
 
 
1103
 
        continue;
1104
 
      }
1105
 
      else if ( list.at( i ).trimmed().startsWith( "Enumerating" ) )
1106
 
      {
1107
 
        continue;
1108
 
      }
1109
 
      else if ( list.at( i ).trimmed().startsWith( "Server name" ) )
1110
 
      {
1111
 
        continue;
1112
 
      }
1113
 
      else if ( list.at( i ).trimmed().startsWith( "-------------" ) )
1114
 
      {
1115
 
        continue;
1116
 
      }
1117
 
      else if ( list.at( i ).trimmed().isEmpty() )
1118
 
      {
1119
 
        continue;
1120
 
      }
1121
 
      else
1122
 
      {
1123
 
        temp_host.setName( list.at( i ).section( "   ", 0, 0 ).trimmed() );
1124
 
        temp_host.setWorkgroup( m_priv->workgroup().name() );
1125
 
        temp_host.setComment( list.at( i ).section( "   ", 1, -1 ).trimmed() );
1126
 
 
1127
 
        // Check if the host is equal to the master browser of the
1128
 
        // workgroup. If it is, copy the IP address and set the master
1129
 
        // browser flag to true.
1130
 
        Smb4KWorkgroup *workgroup = findWorkgroup( temp_host.workgroup() );
1131
 
 
1132
 
        if ( workgroup && QString::compare( temp_host.name(), workgroup->masterBrowserName(), Qt::CaseInsensitive ) == 0 )
1133
 
        {
1134
 
          if ( temp_host.ip().isEmpty() && !workgroup->masterBrowserIP().isEmpty() )
1135
 
          {
1136
 
            temp_host.setIP( workgroup->masterBrowserIP() );
1137
 
          }
1138
 
          else
1139
 
          {
1140
 
            // Do nothing
1141
 
          }
1142
 
 
1143
 
          temp_host.setIsMasterBrowser( true );
1144
 
        }
1145
 
        else
1146
 
        {
1147
 
          // Do nothing
1148
 
        }
1149
 
 
1150
 
        // Search the host in the global list. If it already exists, update it,
1151
 
        // copy it to the temporary list and delete it from the global list
1152
 
        // (it will be reentered in a short moment). If it does not exist yet,
1153
 
        // just copy the temporary host to the list.
1154
 
        Smb4KHost *host = NULL;
1155
 
 
1156
 
        if ( (host = findHost( temp_host.name(), temp_host.workgroup() )) != NULL )
1157
 
        {
1158
 
          host->setComment( temp_host.comment() );
1159
 
 
1160
 
          temp_hosts_list.append( new Smb4KHost( *host ) );
1161
 
 
1162
 
          int index = Smb4KGlobal::hostsList()->indexOf( host );
1163
 
          delete Smb4KGlobal::hostsList()->takeAt( index );
1164
 
        }
1165
 
        else
1166
 
        {
1167
 
          temp_hosts_list.append( new Smb4KHost( temp_host ) );
1168
 
        }
1169
 
 
1170
 
        temp_host = Smb4KHost();
1171
 
 
1172
 
        continue;
1173
 
      }
1174
 
    }
1175
 
 
1176
 
    // If the temporary list should be empty, put at least the master
1177
 
    // browser in.
1178
 
    if ( temp_hosts_list.isEmpty() )
1179
 
    {
1180
 
      temp_host.setName( m_priv->workgroup().masterBrowserName() );
1181
 
      temp_host.setWorkgroup( m_priv->workgroup().name() );
1182
 
      temp_host.setIP( m_priv->workgroup().masterBrowserIP() );
1183
 
      temp_host.setIsMasterBrowser( true );
1184
 
 
1185
 
      temp_hosts_list.append( new Smb4KHost( temp_host ) );
1186
 
    }
1187
 
    else
1188
 
    {
1189
 
      // Do nothing
1190
 
    }
1191
 
 
1192
 
    // Add the temporary hosts list to the global one.
1193
 
    *Smb4KGlobal::hostsList() += temp_hosts_list;
1194
 
 
1195
 
    // Emit the signal that the workgroup members have been
1196
 
    // collected.
1197
 
    emit members( m_priv->workgroup().name(), temp_hosts_list );
1198
 
 
1199
 
    // Lookup missing IP addresses
1200
 
    Smb4KIPAddressScanner::self()->triggerScan();
1201
 
  }
1202
 
  else if ( Smb4KSettings::scanBroadcastAreas() )
1203
 
  {
1204
 
    // We will not remove any host from the list in IP scan mode,
1205
 
    // but we will add additional infomation, if available.
1206
 
    for ( int i = 0; i < list.size(); ++i )
1207
 
    {
1208
 
      if ( list.at( i ).trimmed().startsWith( "Enumerating" ) )
1209
 
      {
1210
 
        continue;
1211
 
      }
1212
 
      else if ( list.at( i ).trimmed().startsWith( "Server name" ) )
1213
 
      {
1214
 
        continue;
1215
 
      }
1216
 
      else if ( list.at( i ).trimmed().startsWith( "-------------" ) )
1217
 
      {
1218
 
        continue;
1219
 
      }
1220
 
      else if ( list.at( i ).trimmed().isEmpty() )
1221
 
      {
1222
 
        continue;
1223
 
      }
1224
 
      else
1225
 
      {
1226
 
        // FIXME: Should we add newly discovered hosts to the global list?
1227
 
 
1228
 
        // Look for a comment and add it to the host item
1229
 
        // if one was found.
1230
 
        if ( !list.at( i ).trimmed().contains( "   " ) )
1231
 
        {
1232
 
          // No comment.
1233
 
          continue;
1234
 
        }
1235
 
        else
1236
 
        {
1237
 
          Smb4KHost *host = findHost( list.at( i ).section( "   ", 0, 0 ).trimmed(),
1238
 
                            m_priv->workgroup().name() );
1239
 
 
1240
 
          if ( host )
1241
 
          {
1242
 
            host->setComment( list.at( i ).section( "   ", 1, -1 ).trimmed() );
1243
 
          }
1244
 
          else
1245
 
          {
1246
 
            // Do nothing.
1247
 
          }
1248
 
        }
1249
 
      }
1250
 
    }
1251
 
 
1252
 
    emit members( m_priv->workgroup().name(), *Smb4KGlobal::hostsList() );
1253
 
  }
1254
 
  else
1255
 
  {
1256
 
    // Do nothing
1257
 
  }
1258
 
 
1259
 
  emit hostListChanged();
1260
 
}
1261
 
 
1262
 
 
1263
 
void Smb4KScanner::processShares()
1264
 
{
1265
 
  // Read from stderr and decide what to do:
1266
 
  QString stderr_output = QString::fromLocal8Bit( m_proc->readAllStandardError(), -1 ).trimmed();
1267
 
 
1268
 
  if ( !stderr_output.isEmpty() )
1269
 
  {
1270
 
    if ( stderr_output.contains( "The username or password was not correct." ) ||
1271
 
         stderr_output.contains( "NT_STATUS_ACCOUNT_DISABLED" ) /* AD error */ ||
1272
 
         stderr_output.contains( "NT_STATUS_ACCESS_DENIED" ) ||
1273
 
         stderr_output.contains( "NT_STATUS_LOGON_FAILURE" ) )
1274
 
    {
1275
 
      // Authentication failed.
1276
 
      emit failed();
1277
 
 
1278
 
      Smb4KAuthInfo authInfo( &m_priv->host() );
1279
 
 
1280
 
      if ( Smb4KWalletManager::self()->showPasswordDialog( &authInfo ) )
1281
 
      {
1282
 
        m_queue.enqueue( QueueContainer( Shares, m_priv->host() ) );
1283
 
      }
1284
 
      else
1285
 
      {
1286
 
        // Do nothing
1287
 
      }
1288
 
      
1289
 
      return;
1290
 
    }
1291
 
    else if ( stderr_output.contains( "could not obtain sid for domain", Qt::CaseSensitive ) )
1292
 
    {
1293
 
      // FIXME: Does this error only occur when we scan a server that is
1294
 
      // only capable of the RAP protocol or also under other conditions?
1295
 
      m_priv->host().setProtocol( Smb4KHost::RAP );
1296
 
 
1297
 
      m_queue.enqueue( QueueContainer( Shares, m_priv->host() ) );
1298
 
 
1299
 
      m_priv->retry = true;
1300
 
      
1301
 
      return;
1302
 
    }
1303
 
    else
1304
 
    {
1305
 
      if ( !stderr_output.contains( "creating lame", Qt::CaseSensitive ) )
1306
 
      {
1307
 
        // We could not get the list of shares:
1308
 
        emit failed();
1309
 
 
1310
 
        // Notify the user:
1311
 
        Smb4KCoreMessage::error( ERROR_GETTING_SHARES, QString(), stderr_output );
1312
 
        
1313
 
        return;
1314
 
      }
1315
 
      else
1316
 
      {
1317
 
        // Do nothing
1318
 
      }
1319
 
    }
1320
 
  }
1321
 
 
1322
 
  // There was no error. We can proceed with processing the
1323
 
  // output from stdout.
1324
 
  QString stdout_output = QString::fromLocal8Bit( m_proc->readAllStandardOutput(), -1 ).trimmed();
1325
 
  QStringList list = stdout_output.split( "\n", QString::SkipEmptyParts );
1326
 
 
1327
 
  QList<Smb4KShare *> temp_shares_list;
1328
 
  Smb4KShare temp_share;
1329
 
 
1330
 
  for ( int i = 0; i < list.size(); ++i )
1331
 
  {
1332
 
    if ( list.at( i ).trimmed().startsWith( "Enumerating" ) )
1333
 
    {
1334
 
      continue;
1335
 
    }
1336
 
    else if ( list.at( i ).trimmed().startsWith( "Share name" ) )
1337
 
    {
1338
 
      continue;
1339
 
    }
1340
 
    else if ( list.at( i ).trimmed().startsWith( "----------" ) )
1341
 
    {
1342
 
      continue;
1343
 
    }
1344
 
    else if ( list.at( i ).trimmed().isEmpty() )
1345
 
    {
1346
 
      continue;
1347
 
    }
1348
 
    else
1349
 
    {
1350
 
      if ( list.at( i ).contains( " Disk     ", Qt::CaseSensitive ) ||
1351
 
           (!list.at( i ).contains( " Disk     ", Qt::CaseSensitive ) &&
1352
 
            list.at( i ).trimmed().endsWith( " Disk", Qt::CaseSensitive )) )
1353
 
      {
1354
 
        if ( !list.at( i ).trimmed().endsWith( " Disk", Qt::CaseSensitive ) )
1355
 
        {
1356
 
          temp_share.setName( list.at( i ).section( " Disk     ", 0, 0 ).trimmed() );
1357
 
          temp_share.setComment( list.at( i ).section( " Disk     ", 1, 1 ).trimmed() );
1358
 
        }
1359
 
        else
1360
 
        {
1361
 
          temp_share.setName( list.at( i ).section( " Disk", 0, 0 ).trimmed() );
1362
 
          temp_share.setComment( "" );
1363
 
        }
1364
 
        
1365
 
        temp_share.setHost( m_priv->host().name() );
1366
 
        temp_share.setWorkgroup( m_priv->host().workgroup() );
1367
 
        temp_share.setType( "Disk" );
1368
 
 
1369
 
        // Check if we also have an IP address we can add to the
1370
 
        // share object.
1371
 
        if ( m_priv->host().ipChecked() && !m_priv->host().ip().isEmpty() )
1372
 
        {
1373
 
          temp_share.setHostIP( m_priv->host().ip() );
1374
 
        }
1375
 
        else
1376
 
        {
1377
 
          Smb4KHost *host = findHost( m_priv->host().name(), m_priv->host().workgroup() );
1378
 
 
1379
 
          if ( host && host->ipChecked() && !host->ip().isEmpty() )
1380
 
          {
1381
 
            temp_share.setHostIP( host->ip() );
1382
 
          }
1383
 
          else
1384
 
          {
1385
 
            // Do nothing
1386
 
          }
1387
 
        }
1388
 
 
1389
 
        // In case this is a 'homes' share, set also the user names.
1390
 
        if ( QString::compare( temp_share.name(), "homes" ) == 0 )
1391
 
        {
1392
 
          Smb4KHomesSharesHandler::self()->setHomesUsers( &temp_share );
1393
 
        }
1394
 
        else
1395
 
        {
1396
 
          // Do nothing
1397
 
        }
1398
 
 
1399
 
        temp_shares_list.append( new Smb4KShare( temp_share ) );
1400
 
 
1401
 
        temp_share = Smb4KShare();
1402
 
 
1403
 
        continue;
1404
 
      }
1405
 
      else if ( list.at( i ).contains( " IPC      ", Qt::CaseSensitive ) ||
1406
 
                (!list.at( i ).contains( " IPC      ", Qt::CaseSensitive ) &&
1407
 
                 list.at( i ).trimmed().endsWith( " IPC", Qt::CaseSensitive )) )
1408
 
      {
1409
 
        if ( !list.at( i ).trimmed().endsWith( " IPC", Qt::CaseSensitive ) )
1410
 
        {
1411
 
          temp_share.setName( list.at( i ).section( " IPC      ", 0, 0 ).trimmed() );
1412
 
          temp_share.setComment( list.at( i ).section( " IPC      ", 1, 1 ).trimmed() );
1413
 
        }
1414
 
        else
1415
 
        {
1416
 
          temp_share.setName( list.at( i ).section( " IPC", 0, 0 ).trimmed() );
1417
 
          temp_share.setComment( "" );
1418
 
        }
1419
 
        
1420
 
        temp_share.setHost( m_priv->host().name() );
1421
 
        temp_share.setWorkgroup( m_priv->host().workgroup() );
1422
 
        temp_share.setType( "IPC" );
1423
 
 
1424
 
        // Check if we also have an IP address we can add to the
1425
 
        // share object.
1426
 
        if ( m_priv->host().ipChecked() && !m_priv->host().ip().isEmpty() )
1427
 
        {
1428
 
          temp_share.setHostIP( m_priv->host().ip() );
1429
 
        }
1430
 
        else
1431
 
        {
1432
 
          Smb4KHost *host = findHost( m_priv->host().name(), m_priv->host().workgroup() );
1433
 
 
1434
 
          if ( host && host->ipChecked() && !host->ip().isEmpty() )
1435
 
          {
1436
 
            temp_share.setHostIP( host->ip() );
1437
 
          }
1438
 
          else
1439
 
          {
1440
 
            // Do nothing
1441
 
          }
1442
 
        }
1443
 
 
1444
 
        temp_shares_list.append( new Smb4KShare( temp_share ) );
1445
 
 
1446
 
        temp_share = Smb4KShare();
1447
 
 
1448
 
        continue;
1449
 
      }
1450
 
      else if ( list.at( i ).contains( " Print    ", Qt::CaseSensitive ) ||
1451
 
                (!list.at( i ).contains( " Print    ", Qt::CaseSensitive ) &&
1452
 
                 list.at( i ).trimmed().endsWith( " Print", Qt::CaseSensitive )) )
1453
 
      {
1454
 
        if ( !list.at( i ).trimmed().endsWith( " Print", Qt::CaseSensitive ) )
1455
 
        {
1456
 
          temp_share.setName( list.at( i ).section( " Print    ", 0, 0 ).trimmed() );
1457
 
          temp_share.setComment( list.at( i ).section( " Print    ", 1, 1 ).trimmed() );
1458
 
        }
1459
 
        else
1460
 
        {
1461
 
          temp_share.setName( list.at( i ).section( " Print", 0, 0 ).trimmed() );
1462
 
          temp_share.setComment( "" );
1463
 
        }
1464
 
        
1465
 
        temp_share.setHost( m_priv->host().name() );
1466
 
        temp_share.setWorkgroup( m_priv->host().workgroup() );
1467
 
        temp_share.setType( "Printer" );
1468
 
 
1469
 
        // Check if we also have an IP address we can add to the
1470
 
        // share object.
1471
 
        if ( m_priv->host().ipChecked() && !m_priv->host().ip().isEmpty() )
1472
 
        {
1473
 
          temp_share.setHostIP( m_priv->host().ip() );
1474
 
        }
1475
 
        else
1476
 
        {
1477
 
          Smb4KHost *host = findHost( m_priv->host().name(), m_priv->host().workgroup() );
1478
 
 
1479
 
          if ( host && host->ipChecked() && !host->ip().isEmpty() )
1480
 
          {
1481
 
            temp_share.setHostIP( host->ip() );
1482
 
          }
1483
 
          else
1484
 
          {
1485
 
            // Do nothing
1486
 
          }
1487
 
        }
1488
 
 
1489
 
        // Printer shares cannot be mounted, thus we do not need to check
1490
 
        // here if it is.
1491
 
 
1492
 
        temp_shares_list.append( new Smb4KShare( temp_share ) );
1493
 
 
1494
 
        temp_share = Smb4KShare();
1495
 
 
1496
 
        continue;
1497
 
      }
1498
 
      else
1499
 
      {
1500
 
        continue;
1501
 
      }
1502
 
    }
1503
 
 
1504
 
    continue;
1505
 
  }
1506
 
 
1507
 
  // Check if a share in the list is mounted.
1508
 
  for ( int i = 0; i < temp_shares_list.size(); ++i )
1509
 
  {
1510
 
    for ( int j = 0; j < Smb4KGlobal::mountedSharesList()->size(); ++j )
1511
 
    {
1512
 
      if ( QString::compare( Smb4KGlobal::mountedSharesList()->at( j )->host(), temp_shares_list.at( i )->host() ) == 0 &&
1513
 
           QString::compare( Smb4KGlobal::mountedSharesList()->at( j )->name(), temp_shares_list.at( i )->name() ) == 0 )
1514
 
      {
1515
 
        temp_shares_list.at( i )->setMountData( Smb4KGlobal::mountedSharesList()->at( j ) );
1516
 
 
1517
 
        break;
1518
 
      }
1519
 
      else
1520
 
      {
1521
 
        continue;
1522
 
      }
1523
 
    }
1524
 
  }
1525
 
 
1526
 
  emit shares( m_priv->host().name(), temp_shares_list );
1527
 
}
1528
 
 
1529
 
 
1530
 
void Smb4KScanner::processInfo( QProcess::ExitStatus status )
1531
 
{
1532
 
  switch ( status )
1533
 
  {
1534
 
    case QProcess::NormalExit:
1535
 
    {
1536
 
      // Since the information about the server and operating system
1537
 
      // is debug information, it will be reported via stderr.
1538
 
      QString stderr_output = QString::fromLocal8Bit( m_proc->readAllStandardError(), -1 ).trimmed();
1539
 
 
1540
 
      // Get the host.
1541
 
      Smb4KHost *host = findHost( m_priv->host().name(), m_priv->host().workgroup() );
1542
 
 
1543
 
      if ( host )
1544
 
      {
1545
 
        // The output should only be one line, so we can process it
1546
 
        // immediately.
1547
 
        if ( stderr_output.trimmed().startsWith( "Domain" ) || stderr_output.trimmed().startsWith( "OS" ) )
1548
 
        {
1549
 
          host->setInfo( stderr_output.section( "Server=[", 1, 1 ).section( "]", 0, 0 ).trimmed(),
1550
 
                         stderr_output.section( "OS=[", 1, 1 ).section( "]", 0, 0 ).trimmed() );
1551
 
        }
1552
 
        else
1553
 
        {
1554
 
          emit failed();
1555
 
        }
1556
 
 
1557
 
        emit info( host );
1558
 
      }
1559
 
      else
1560
 
      {
1561
 
        // Do nothing
1562
 
      }
1563
 
 
1564
 
      break;
1565
 
    }
1566
 
    default:
1567
 
    {
1568
 
      // Enable checking again.
1569
 
      Smb4KHost *host = findHost( m_priv->host().name(), m_priv->host().workgroup() );
1570
 
 
1571
 
      if ( host )
1572
 
      {
1573
 
        host->resetInfo();
1574
 
      }
1575
 
      else
1576
 
      {
1577
 
        // Do nothing
1578
 
      }
1579
 
    }
1580
 
  }
1581
 
}
1582
 
 
1583
 
 
1584
 
void Smb4KScanner::insertHost( Smb4KHost *host )
1585
 
{
1586
 
  if ( host && !findHost( host->name(), host->workgroup() ) )
1587
 
  {
1588
 
    // Use the copy constructor here, so that we do not run into
1589
 
    // trouble when/if host is deleted.
1590
 
    Smb4KHost *new_host = new Smb4KHost( *host );
1591
 
 
1592
 
    Smb4KGlobal::hostsList()->append( new_host );
1593
 
 
1594
 
    // Check if the workgroup is already known. If not, create a new Smb4KWorkgroup object,
1595
 
    // declare the host a pseudo master and add the workgroup to the list.
1596
 
    if ( !findWorkgroup( new_host->workgroup() ) )
1597
 
    {
1598
 
      Smb4KWorkgroup *workgroup = new Smb4KWorkgroup( new_host->workgroup() );
1599
 
      workgroup->setMasterBrowser( new_host->name(), new_host->ip(), true );
1600
 
 
1601
 
      new_host->setIsMasterBrowser( true );  // pseudo master
1602
 
 
1603
 
      appendWorkgroup( workgroup );
1604
 
    }
1605
 
 
1606
 
    // Lookup at least the IP address of this host, if necessary:
1607
 
    if ( new_host->ip().isEmpty() )
1608
 
    {
1609
 
      Smb4KIPAddressScanner::self()->triggerScan();
1610
 
    }
1611
 
 
1612
 
    emit hostInserted( new_host );
1613
 
    emit hostListChanged();
1614
 
  }
1615
 
}
1616
 
 
1617
 
 
1618
 
void Smb4KScanner::appendWorkgroup( Smb4KWorkgroup *workgroup )
1619
 
{
1620
 
  if ( !findWorkgroup( workgroup->name() ) )
1621
 
  {
1622
 
    // Append the workgroup.
1623
 
    Smb4KGlobal::workgroupsList()->append( workgroup );
1624
 
 
1625
 
    // Add the master browser to the list of hosts.
1626
 
    if ( !workgroup->masterBrowserName().isEmpty() )
1627
 
    {
1628
 
      Smb4KHost *master_browser = new Smb4KHost( workgroup->masterBrowserName() );
1629
 
      master_browser->setWorkgroup( workgroup->name() );
1630
 
      master_browser->setIP( workgroup->masterBrowserIP() );
1631
 
    }
1632
 
 
1633
 
    emit workgroups( *Smb4KGlobal::workgroupsList() );
1634
 
    emit hostListChanged();
1635
 
  }
1636
 
  else
1637
 
  {
1638
 
    // Do nothing
1639
 
  }
1640
 
}
1641
 
 
1642
 
 
1643
 
void Smb4KScanner::timerEvent( QTimerEvent * )
1644
 
{
1645
 
  if ( !m_working && !m_queue.isEmpty() )
1646
 
  {
1647
 
    // Tell the program, that the scanner is running.
1648
 
    m_working = true;
1649
 
 
1650
 
    QueueContainer c = m_queue.dequeue();
1651
 
 
1652
 
    switch ( c.todo() )
1653
 
    {
1654
 
      case Init:
1655
 
      {
1656
 
        if ( Smb4KSettings::lookupDomains() )
1657
 
        {
1658
 
          emit state( SCANNER_LOOKUP_DOMAINS );
 
650
    return;
 
651
  }
 
652
  else
 
653
  {
 
654
    // Do nothing
 
655
  }
 
656
  
 
657
  Smb4KLookupInfoJob *job = new Smb4KLookupInfoJob( this );
 
658
  job->setObjectName( QString( "LookupInfoJob_%1" ).arg( host->hostName() ) );
 
659
  job->setupLookup( host, parent );
 
660
    
 
661
  connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
662
  connect( job, SIGNAL( aboutToStart( Smb4KHost * ) ), SLOT( slotAboutToStartSharesLookup( Smb4KHost * ) ) );
 
663
  connect( job, SIGNAL( finished( Smb4KHost * ) ), SLOT( slotSharesLookupFinished( Smb4KHost * ) ) );
 
664
  connect( job, SIGNAL( info( Smb4KHost * ) ), SLOT( slotInfo( Smb4KHost * ) ) );
 
665
    
 
666
  if ( !hasSubjobs() )
 
667
  {
 
668
    QApplication::setOverrideCursor( Qt::BusyCursor );
 
669
  }
 
670
  else
 
671
  {
 
672
    // Do nothing
 
673
  }
 
674
 
 
675
  addSubjob( job );
 
676
 
 
677
  job->start();
 
678
}
 
679
 
 
680
 
 
681
void Smb4KScanner::timerEvent( QTimerEvent */*e*/ )
 
682
{
 
683
  if ( Smb4KSettings::periodicScanning() )
 
684
  {
 
685
    if ( m_interval == 0 )
 
686
    {
 
687
      if ( m_periodic_jobs.isEmpty() )
 
688
      {
 
689
        // This case occurs when the user enables periodic scanning during
 
690
        // runtime. We need to fill the list of periodic jobs here, so that
 
691
        // we can immediately start periodic scanning.
 
692
        m_periodic_jobs << LookupDomains;
 
693
        m_periodic_jobs << LookupDomainMembers;
 
694
        m_periodic_jobs << LookupShares;
 
695
      }
 
696
      else
 
697
      {
 
698
        // This is the regular case. We do not need to do anything.
 
699
      }
 
700
 
 
701
      Process p = m_periodic_jobs.takeFirst();
 
702
 
 
703
      switch ( p )
 
704
      {
 
705
        case LookupDomains:
 
706
        {
 
707
          m_scanning_allowed = false;
1659
708
          lookupDomains();
1660
 
        }
1661
 
        else if ( Smb4KSettings::queryCurrentMaster() ||
1662
 
                  Smb4KSettings::queryCustomMaster() )
1663
 
        {
1664
 
          emit state( SCANNER_QUERY_MASTER_BROWSER );
1665
 
          queryMasterBrowser();
1666
 
        }
1667
 
        else if ( Smb4KSettings::scanBroadcastAreas() )
1668
 
        {
1669
 
          emit state( SCANNER_SCAN_BROADCAST_AREAS );
1670
 
          scanBroadcastAreas();
 
709
          break;
 
710
        }
 
711
        default:
 
712
        {
 
713
          break;
 
714
        }
 
715
      }
 
716
    }
 
717
    else
 
718
    {
 
719
      if ( m_interval >= (Smb4KSettings::scanInterval() * 60000 /* milliseconds */) )
 
720
      {
 
721
        // Reset interval. Since the check above 
 
722
        m_interval = -TIMER_INTERVAL;
 
723
 
 
724
        // Fill list
 
725
        m_periodic_jobs << LookupDomains;
 
726
        m_periodic_jobs << LookupDomainMembers;
 
727
        m_periodic_jobs << LookupShares;
 
728
      }
 
729
      else
 
730
      {
 
731
        // Check if we need to do something.
 
732
        // Do not start any process before the previous has not finished.
 
733
        if ( !m_periodic_jobs.isEmpty() && m_scanning_allowed )
 
734
        {
 
735
          Process p = m_periodic_jobs.takeFirst();
 
736
 
 
737
          switch ( p )
 
738
          {
 
739
            case LookupDomainMembers:
 
740
            {
 
741
              for ( int i = 0; i < workgroupsList().size(); ++i )
 
742
              {
 
743
                m_scanning_allowed = false;
 
744
                lookupDomainMembers( workgroupsList()[i] );
 
745
              }
 
746
              break;
 
747
            }
 
748
            case LookupShares:
 
749
            {
 
750
              for ( int i = 0; i < hostsList().size(); ++i )
 
751
              {
 
752
                m_scanning_allowed = false;
 
753
                lookupShares( hostsList()[i] );
 
754
              }
 
755
              break;
 
756
            }
 
757
            default:
 
758
            {
 
759
              break;
 
760
            }
 
761
          };
1671
762
        }
1672
763
        else
1673
764
        {
1674
765
          // Do nothing
1675
766
        }
1676
 
 
1677
 
        break;
1678
 
      }
1679
 
      case Hosts:
1680
 
      {
1681
 
        emit state( SCANNER_OPEN_WORKGROUP );
1682
 
        scanForWorkgroupMembers( c.workgroup() );
1683
 
        break;
1684
 
      }
1685
 
      case Shares:
1686
 
      {
1687
 
        emit state( SCANNER_OPEN_HOST );
1688
 
 
1689
 
        if ( m_priv->retry )
1690
 
        {
1691
 
          m_priv->retry = false;
1692
 
        }
1693
 
 
1694
 
        scanForShares( c.host() );
1695
 
        break;
1696
 
      }
1697
 
      case Info:
1698
 
      {
1699
 
        emit state( SCANNER_QUERY_INFO );
1700
 
        scanForInfo( c.host() );
1701
 
        break;
1702
 
      }
1703
 
      default:
1704
 
      {
1705
 
        break;
1706
767
      }
1707
768
    }
 
769
 
 
770
    m_interval += TIMER_INTERVAL;
1708
771
  }
1709
772
  else
1710
773
  {
1711
 
    // Do nothing
 
774
    // Periodic scanning is not enabled or has been disabled
 
775
    // during runtime. So, reset the interval, if necessary.
 
776
    if ( m_interval != 0 )
 
777
    {
 
778
      m_interval = 0;
 
779
    }
 
780
    else
 
781
    {
 
782
      // Do nothing
 
783
    }
1712
784
  }
1713
785
}
1714
786
 
1715
787
 
 
788
 
1716
789
/////////////////////////////////////////////////////////////////////////////
1717
790
// SLOT IMPLEMENTATIONS
1718
791
/////////////////////////////////////////////////////////////////////////////
1719
792
 
1720
 
 
1721
 
void Smb4KScanner::slotProcessFinished( int exitCode, QProcess::ExitStatus exitStatus )
1722
 
{
1723
 
  endProcess( exitCode, exitStatus );
1724
 
}
1725
 
 
1726
 
 
1727
 
void Smb4KScanner::slotProcessError( QProcess::ProcessError errorCode )
1728
 
{
1729
 
  m_process_error = errorCode;
1730
 
}
1731
 
 
1732
 
 
1733
 
#include <smb4kscanner.moc>
 
793
void Smb4KScanner::slotAboutToQuit()
 
794
{
 
795
  abortAll();
 
796
}
 
797
 
 
798
 
 
799
void Smb4KScanner::slotStartJobs()
 
800
{
 
801
  // If the user wants to have periodic scanning of the network
 
802
  // neighborhood, set it up here here.
 
803
  if ( Smb4KSettings::periodicScanning() )
 
804
  {
 
805
    // Fill list
 
806
    m_periodic_jobs << LookupDomains;
 
807
    m_periodic_jobs << LookupDomainMembers;
 
808
    m_periodic_jobs << LookupShares;
 
809
  }
 
810
  else
 
811
  {
 
812
    lookupDomains( 0 );
 
813
  }
 
814
  
 
815
  // Start the timer in any case. Thus, we are able to switch
 
816
  // to periodic scanning seamlessly in the timerEvent() function.
 
817
  startTimer( TIMER_INTERVAL );
 
818
}
 
819
 
 
820
 
 
821
void Smb4KScanner::slotJobFinished( KJob *job )
 
822
{
 
823
  removeSubjob( job );
 
824
 
 
825
  if ( !hasSubjobs() )
 
826
  {
 
827
    QApplication::restoreOverrideCursor();
 
828
  }
 
829
  else
 
830
  {
 
831
    // Do nothing
 
832
  }
 
833
}
 
834
 
 
835
 
 
836
void Smb4KScanner::slotAuthError( Smb4KQueryMasterJob *job )
 
837
{
 
838
  Smb4KHost master_browser;
 
839
  
 
840
  if ( !job->masterBrowser().isEmpty() )
 
841
  {
 
842
    master_browser.setIsMasterBrowser( true );
 
843
 
 
844
    if ( QHostAddress( job->masterBrowser() ).protocol() == QAbstractSocket::UnknownNetworkLayerProtocol )
 
845
    {
 
846
      master_browser.setHostName( job->masterBrowser() );
 
847
    }
 
848
    else
 
849
    {
 
850
      master_browser.setIP( job->masterBrowser() );
 
851
    }
 
852
    
 
853
    emit authError ( &master_browser, LookupDomains );
 
854
  }
 
855
  else
 
856
  {
 
857
    // Do nothing
 
858
  }
 
859
 
 
860
  if ( Smb4KWalletManager::self()->showPasswordDialog( &master_browser, job->parentWidget() ) )
 
861
  {
 
862
    // Start a query job with the returned master browser.
 
863
    Smb4KQueryMasterJob *job = new Smb4KQueryMasterJob( this );
 
864
    job->setObjectName( "LookupDomainsJob" );
 
865
    job->setupLookup( job->masterBrowser(), job->parentWidget() );
 
866
 
 
867
    connect( job, SIGNAL( result( KJob * ) ), SLOT( slotJobFinished( KJob * ) ) );
 
868
    connect( job, SIGNAL( aboutToStart() ), SLOT( slotAboutToStartDomainsLookup() ) );
 
869
    connect( job, SIGNAL( finished() ), SLOT( slotDomainsLookupFinished() ) );
 
870
    connect( job, SIGNAL( workgroups( const QList<Smb4KWorkgroup> & ) ), SLOT( slotWorkgroups( const QList<Smb4KWorkgroup> & ) ) );
 
871
    connect( job, SIGNAL( authError( Smb4KQueryMasterJob * ) ), SLOT( slotAuthError( Smb4KQueryMasterJob * ) ) );
 
872
 
 
873
    if ( !hasSubjobs() )
 
874
    {
 
875
      QApplication::setOverrideCursor( Qt::BusyCursor );
 
876
    }
 
877
    else
 
878
    {
 
879
      // Do nothing
 
880
    }
 
881
 
 
882
    addSubjob( job );
 
883
 
 
884
    job->start();
 
885
  }
 
886
  else
 
887
  {
 
888
    // Do nothing
 
889
  }
 
890
}
 
891
 
 
892
 
 
893
void Smb4KScanner::slotAuthError( Smb4KLookupDomainMembersJob *job )
 
894
{
 
895
  Smb4KHost *master_browser = findHost( job->workgroup()->masterBrowserName(), job->workgroup()->workgroupName() );
 
896
  
 
897
  if ( master_browser )
 
898
  {
 
899
    emit authError( master_browser, LookupDomainMembers );
 
900
    
 
901
    if ( Smb4KWalletManager::self()->showPasswordDialog( master_browser, job->parentWidget() ) )
 
902
    {
 
903
      lookupDomainMembers( job->workgroup(), job->parentWidget() );
 
904
    }
 
905
    else
 
906
    {
 
907
      // Do nothing
 
908
    }
 
909
  }
 
910
  else
 
911
  {
 
912
    // Do nothing
 
913
  }
 
914
}
 
915
 
 
916
 
 
917
void Smb4KScanner::slotAuthError( Smb4KLookupSharesJob *job )
 
918
{
 
919
  Smb4KHost *host = findHost( job->host()->hostName(), job->host()->workgroupName() );
 
920
  
 
921
  if ( host )
 
922
  {
 
923
    emit authError( host, LookupShares );
 
924
    
 
925
    if ( Smb4KWalletManager::self()->showPasswordDialog( host, job->parentWidget() ) )
 
926
    {
 
927
      lookupShares( host, job->parentWidget() );
 
928
    }
 
929
    else
 
930
    {
 
931
      // Do nothing
 
932
    }
 
933
  }
 
934
  else
 
935
  {
 
936
    // Do nothing
 
937
  }
 
938
}
 
939
 
 
940
 
 
941
void Smb4KScanner::slotAboutToStartDomainsLookup()
 
942
{
 
943
  Smb4KBasicNetworkItem item;
 
944
  emit aboutToStart( &item, LookupDomains );
 
945
}
 
946
 
 
947
 
 
948
void Smb4KScanner::slotDomainsLookupFinished()
 
949
{
 
950
  Smb4KBasicNetworkItem item;
 
951
  emit finished( &item, LookupDomains );
 
952
  m_scanning_allowed = true;
 
953
}
 
954
 
 
955
 
 
956
void Smb4KScanner::slotAboutToStartHostsLookup( Smb4KWorkgroup *workgroup )
 
957
{
 
958
  emit aboutToStart( workgroup, LookupDomainMembers );
 
959
}
 
960
 
 
961
 
 
962
void Smb4KScanner::slotHostsLookupFinished( Smb4KWorkgroup *workgroup )
 
963
{
 
964
  emit finished( workgroup, LookupDomainMembers );
 
965
  m_scanning_allowed = true;
 
966
}
 
967
 
 
968
 
 
969
void Smb4KScanner::slotAboutToStartSharesLookup( Smb4KHost *host )
 
970
{
 
971
  emit aboutToStart( host, LookupShares );
 
972
}
 
973
 
 
974
 
 
975
void Smb4KScanner::slotSharesLookupFinished( Smb4KHost *host )
 
976
{
 
977
  emit finished( host, LookupShares );
 
978
  m_scanning_allowed = true;
 
979
}
 
980
 
 
981
 
 
982
void Smb4KScanner::slotAboutToStartInfoLookup( Smb4KHost *host )
 
983
{
 
984
  emit aboutToStart( host, LookupInfo );
 
985
}
 
986
 
 
987
 
 
988
void Smb4KScanner::slotInfoLookupFinished( Smb4KHost *host )
 
989
{
 
990
  emit finished( host, LookupInfo );
 
991
}
 
992
 
 
993
 
 
994
void Smb4KScanner::slotWorkgroups( const QList<Smb4KWorkgroup> &workgroups_list )
 
995
{
 
996
  // The new workgroup list will be used as global workgroup list.
 
997
  // We do some checks and adjustments now, so that the host list 
 
998
  // is also correctly updated.
 
999
  if ( !workgroups_list.isEmpty() )
 
1000
  {
 
1001
    for ( int i = 0; i < workgroups_list.size(); ++i )
 
1002
    {
 
1003
      Smb4KWorkgroup *workgroup = findWorkgroup( workgroups_list.at( i ).workgroupName() );
 
1004
 
 
1005
      // Check if the master browser changed.
 
1006
      if ( workgroup )
 
1007
      {
 
1008
        if ( QString::compare( workgroups_list.at( i ).masterBrowserName(), workgroup->masterBrowserName(), Qt::CaseInsensitive ) != 0 )
 
1009
        {
 
1010
          // Get the old master browser and reset the master browser flag.
 
1011
          Smb4KHost *old_master_browser = findHost( workgroup->masterBrowserName(), workgroup->workgroupName() );
 
1012
 
 
1013
          if ( old_master_browser )
 
1014
          {
 
1015
            old_master_browser->setIsMasterBrowser( false );
 
1016
          }
 
1017
          else
 
1018
          {
 
1019
            // Do nothing
 
1020
          }
 
1021
 
 
1022
          // Lookup new master browser and either set the master browser flag
 
1023
          // or insert it if it does not exit yet.
 
1024
          Smb4KHost *new_master_browser = findHost( workgroups_list.at( i ).masterBrowserName(), workgroups_list.at( i ).workgroupName() );
 
1025
 
 
1026
          if ( new_master_browser )
 
1027
          {
 
1028
            if ( workgroups_list.at( i ).hasMasterBrowserIP() )
 
1029
            {
 
1030
              new_master_browser->setIP( workgroups_list.at( i ).masterBrowserIP() );
 
1031
            }
 
1032
            else
 
1033
            {
 
1034
              // Do nothing
 
1035
            }
 
1036
 
 
1037
            new_master_browser->setIsMasterBrowser( true );
 
1038
          }
 
1039
          else
 
1040
          {
 
1041
            new_master_browser = new Smb4KHost();
 
1042
            new_master_browser->setHostName( workgroups_list.at( i ).masterBrowserName() );
 
1043
 
 
1044
            if ( workgroups_list.at( i ).hasMasterBrowserIP() )
 
1045
            {
 
1046
              new_master_browser->setIP( workgroups_list.at( i ).masterBrowserIP() );
 
1047
            }
 
1048
            else
 
1049
            {
 
1050
              // Do nothing
 
1051
            }
 
1052
 
 
1053
            new_master_browser->setWorkgroupName( workgroups_list.at( i ).workgroupName() );
 
1054
            new_master_browser->setIsMasterBrowser( true );
 
1055
 
 
1056
            addHost( new_master_browser );
 
1057
          }
 
1058
        }
 
1059
        else
 
1060
        {
 
1061
          // Do nothing
 
1062
        }
 
1063
 
 
1064
        removeWorkgroup( workgroup );
 
1065
      }
 
1066
      else
 
1067
      {
 
1068
        // Check if the master browser of the new workgroup list is by chance
 
1069
        // already in the list of hosts. If it exists, set the master browser
 
1070
        // flag, else insert it.
 
1071
        Smb4KHost *new_master_browser = findHost( workgroups_list.at( i ).masterBrowserName(), workgroups_list.at( i ).workgroupName() );
 
1072
 
 
1073
        if ( new_master_browser )
 
1074
        {
 
1075
          if ( workgroups_list.at( i ).hasMasterBrowserIP() )
 
1076
          {
 
1077
            new_master_browser->setIP( workgroups_list.at( i ).masterBrowserIP() );
 
1078
          }
 
1079
          else
 
1080
          {
 
1081
            // Do nothing
 
1082
          }
 
1083
 
 
1084
          new_master_browser->setIsMasterBrowser( true );
 
1085
        }
 
1086
        else
 
1087
        {
 
1088
          new_master_browser = new Smb4KHost();
 
1089
          new_master_browser->setHostName( workgroups_list.at( i ).masterBrowserName() );
 
1090
 
 
1091
          if ( workgroups_list.at( i ).hasMasterBrowserIP() )
 
1092
          {
 
1093
            new_master_browser->setIP( workgroups_list.at( i ).masterBrowserIP() );
 
1094
          }
 
1095
          else
 
1096
          {
 
1097
            // Do nothing
 
1098
          }
 
1099
 
 
1100
          new_master_browser->setWorkgroupName( workgroups_list.at( i ).workgroupName() );
 
1101
          new_master_browser->setIsMasterBrowser( true );
 
1102
 
 
1103
          addHost( new_master_browser );
 
1104
        }
 
1105
      }
 
1106
    }
 
1107
  }
 
1108
  else
 
1109
  {
 
1110
    // Do nothing
 
1111
  }
 
1112
 
 
1113
  // The global workgroup list only contains obsolete workgroups now.
 
1114
  // Remove all hosts belonging to those obsolete workgroups from the
 
1115
  // host list and then also the workgroups themselves.
 
1116
  while ( !workgroupsList().isEmpty() )
 
1117
  {
 
1118
    Smb4KWorkgroup *workgroup = workgroupsList().first();
 
1119
    QList<Smb4KHost *> obsolete_hosts = workgroupMembers( workgroup );
 
1120
    QListIterator<Smb4KHost *> h( obsolete_hosts );
 
1121
    
 
1122
    while ( h.hasNext() )
 
1123
    {
 
1124
      Smb4KHost *host = h.next();
 
1125
      removeHost( host );
 
1126
    }
 
1127
 
 
1128
    removeWorkgroup( workgroup );
 
1129
  }
 
1130
 
 
1131
  // Add a copy of all workgroups to the global list.
 
1132
  for ( int i = 0; i < workgroups_list.size(); ++i )
 
1133
  {
 
1134
    addWorkgroup( new Smb4KWorkgroup( workgroups_list.at( i ) ) );
 
1135
  }
 
1136
 
 
1137
  // Scan for IP addresses if necessary
 
1138
  if ( !Smb4KSettings::scanBroadcastAreas() )
 
1139
  {
 
1140
    Smb4KIPAddressScanner::self()->lookup();
 
1141
  }
 
1142
  else
 
1143
  {
 
1144
    // Do nothing
 
1145
  }
 
1146
 
 
1147
  emit workgroups( workgroupsList() );
 
1148
  emit hostListChanged();  
 
1149
}
 
1150
 
 
1151
 
 
1152
void Smb4KScanner::slotHosts( const QList<Smb4KHost> &hosts_list )
 
1153
{
 
1154
  slotHosts( NULL, hosts_list );
 
1155
}
 
1156
 
 
1157
 
 
1158
void Smb4KScanner::slotHosts( Smb4KWorkgroup *workgroup, const QList<Smb4KHost> &hosts_list )
 
1159
{
 
1160
  QList<Smb4KHost> internal_hosts_list;
 
1161
  
 
1162
  if ( !hosts_list.isEmpty() )
 
1163
  {
 
1164
    // Copy any information we might need to the internal list and
 
1165
    // remove the host from the global list. It will be added again
 
1166
    // in an instant.
 
1167
    for ( int i = 0; i < hosts_list.size(); ++i )
 
1168
    {
 
1169
      Smb4KHost new_host = hosts_list[i];
 
1170
      Smb4KHost *host = findHost( new_host.hostName(), new_host.workgroupName() );
 
1171
 
 
1172
      if ( host )
 
1173
      {
 
1174
        // Set comment
 
1175
        if ( new_host.comment().isEmpty() && !host->comment().isEmpty() )
 
1176
        {
 
1177
          new_host.setComment( host->comment() );
 
1178
        }
 
1179
        else
 
1180
        {
 
1181
          // Do nothing
 
1182
        }
 
1183
 
 
1184
        // Set the additional information
 
1185
        if ( !new_host.infoChecked() && host->infoChecked() )
 
1186
        {
 
1187
          new_host.setInfo( host->serverString(), host->osString() );
 
1188
        }
 
1189
        else
 
1190
        {
 
1191
          // Do nothing
 
1192
        }
 
1193
 
 
1194
        // Set the IP addresses
 
1195
        if ( !new_host.hasIP() && host->hasIP() )
 
1196
        {
 
1197
          new_host.setIP( host->ip() );
 
1198
        }
 
1199
        else
 
1200
        {
 
1201
          // Do nothing
 
1202
        }
 
1203
 
 
1204
        removeHost( host );
 
1205
      }
 
1206
      else
 
1207
      {
 
1208
        // Do nothing
 
1209
      }
 
1210
      
 
1211
      internal_hosts_list << new_host;
 
1212
    }
 
1213
  }
 
1214
  else
 
1215
  {
 
1216
    // Do nothing
 
1217
  }
 
1218
 
 
1219
  if ( workgroup )
 
1220
  {
 
1221
    // Now remove all (obsolete) hosts of the scanned workgroup from
 
1222
    // the global list as well as their shares.
 
1223
    QList<Smb4KHost *> obsolete_hosts = workgroupMembers( workgroup );
 
1224
    QListIterator<Smb4KHost *> h( obsolete_hosts );
 
1225
    
 
1226
    while ( h.hasNext() )
 
1227
    {
 
1228
      Smb4KHost *host = h.next();
 
1229
      
 
1230
      QList<Smb4KShare *> obsolete_shares = sharedResources( host );
 
1231
      QListIterator<Smb4KShare *> s( obsolete_shares );
 
1232
      
 
1233
      while ( s.hasNext() )
 
1234
      {
 
1235
        Smb4KShare *share = s.next();
 
1236
        removeShare( share );
 
1237
      }
 
1238
      
 
1239
      removeHost( host );
 
1240
    }
 
1241
  }
 
1242
  else
 
1243
  {
 
1244
    // If no workgroup was passed it means that we are doing an IP scan
 
1245
    // or at least members of more than one workgroup were looked up. In
 
1246
    // this case the global hosts list is considered to carry obsolete
 
1247
    // host entries at this point. Remove them as well as their shares.
 
1248
    while ( !hostsList().isEmpty() )
 
1249
    {
 
1250
      Smb4KHost *host = hostsList().first();
 
1251
 
 
1252
      QList<Smb4KShare *> obsolete_shares = sharedResources( host );
 
1253
      QListIterator<Smb4KShare *> s( obsolete_shares );
 
1254
      
 
1255
      while ( s.hasNext() )
 
1256
      {
 
1257
        Smb4KShare *share = s.next();
 
1258
        removeShare( share );
 
1259
      }
 
1260
      
 
1261
      removeHost( host );
 
1262
    }
 
1263
  }
 
1264
  
 
1265
  // Add a copy of all hosts to the global list.
 
1266
  for ( int i = 0; i < internal_hosts_list.size(); ++i )
 
1267
  {
 
1268
    addHost( new Smb4KHost( internal_hosts_list.at( i ) ) );
 
1269
  }
 
1270
 
 
1271
  // Scan for IP addresses if necessary
 
1272
  if ( !internal_hosts_list.isEmpty() && !Smb4KSettings::scanBroadcastAreas() )
 
1273
  {
 
1274
    Smb4KIPAddressScanner::self()->lookup();
 
1275
  }
 
1276
  else
 
1277
  {
 
1278
    // Do nothing
 
1279
  }
 
1280
  
 
1281
  if ( workgroup )
 
1282
  {
 
1283
    QList<Smb4KHost *> workgroup_members = workgroupMembers( workgroup );
 
1284
    emit hosts( workgroup, workgroup_members );
 
1285
  }
 
1286
  else
 
1287
  {
 
1288
    emit hosts( workgroup, hostsList() );
 
1289
  }
 
1290
  emit hostListChanged();
 
1291
}
 
1292
 
 
1293
 
 
1294
void Smb4KScanner::slotShares( Smb4KHost *host, const QList<Smb4KShare> &shares_list )
 
1295
{
 
1296
  Q_ASSERT( host );
 
1297
  
 
1298
  QList<Smb4KShare> internal_shares_list;
 
1299
  
 
1300
  if ( !shares_list.isEmpty() )
 
1301
  {
 
1302
    // Copy some information before processing the shares further. 
 
1303
    // Note, that the IP address and other information stemming from
 
1304
    // the host were already entered by the lookup job.
 
1305
    for ( int i = 0; i < shares_list.size(); ++i )
 
1306
    {
 
1307
      Smb4KShare new_share = shares_list[i];
 
1308
      
 
1309
      // Check if the share has already been mounted.
 
1310
      QList<Smb4KShare *> mounted_shares = findShareByUNC( new_share.unc() );
 
1311
      
 
1312
      if ( !mounted_shares.isEmpty() )
 
1313
      {
 
1314
        // FIXME: We cannot honor Smb4KSettings::showAllShares() here, because 
 
1315
        // in case the setting is changed, there will be no automatic rescan
 
1316
        // (in case of an automatic or periodical rescan that would be the 
 
1317
        // favorable method...
 
1318
        //
 
1319
        // For now, we prefer the share mounted by the user or use the first
 
1320
        // occurrence if he/she did not mount it.
 
1321
        Smb4KShare *mounted_share = mounted_shares.first();
 
1322
        
 
1323
        for ( int j = 0; j < mounted_shares.size(); ++j )
 
1324
        {
 
1325
          if ( !mounted_shares.at( j )->isForeign() )
 
1326
          {
 
1327
            mounted_share = mounted_shares[j];
 
1328
            break;
 
1329
          }
 
1330
          else
 
1331
          {
 
1332
            continue;
 
1333
          }
 
1334
        }
 
1335
        
 
1336
        new_share.setMountData( mounted_share );
 
1337
      }
 
1338
      else
 
1339
      {
 
1340
        // Do nothing
 
1341
      }
 
1342
      
 
1343
      // Now set some information that might have been collected
 
1344
      // since the lookup started...
 
1345
      Smb4KShare *share = findShare( new_share.shareName(), new_share.hostName(), new_share.workgroupName() );
 
1346
        
 
1347
      if ( share )
 
1348
      {
 
1349
        if ( !new_share.hasHostIP() && share->hasHostIP() )
 
1350
        {
 
1351
          new_share.setHostIP( share->hostIP() );
 
1352
        }
 
1353
        else
 
1354
        {
 
1355
          // Do nothing
 
1356
        }
 
1357
          
 
1358
        removeShare( share );
 
1359
      }
 
1360
      else
 
1361
      {
 
1362
        // Do nothing
 
1363
      }
 
1364
        
 
1365
      internal_shares_list << new_share;
 
1366
    }
 
1367
  }
 
1368
  else
 
1369
  {
 
1370
    // Do nothing
 
1371
  }
 
1372
  
 
1373
  // Copy authentication information
 
1374
  Smb4KHost *known_host = findHost( host->hostName(), host->workgroupName() );
 
1375
  
 
1376
  if ( known_host )
 
1377
  {
 
1378
    known_host->setLogin( host->login() );
 
1379
    known_host->setPassword( host->password() );
 
1380
  }
 
1381
  else
 
1382
  {
 
1383
    // Do nothing
 
1384
  }
 
1385
  
 
1386
  // Now remove all (obsolete) shares of the scanned host from
 
1387
  // the global list.
 
1388
  QList<Smb4KShare *> obsolete_shares = sharedResources( host );
 
1389
  QListIterator<Smb4KShare *> s( obsolete_shares );
 
1390
    
 
1391
  while ( s.hasNext() )
 
1392
  {
 
1393
    Smb4KShare *share = s.next();
 
1394
    removeShare( share );
 
1395
  }
 
1396
  
 
1397
  // Add a copy of all shares to the global list.
 
1398
  for ( int i = 0; i < internal_shares_list.size(); ++i )
 
1399
  {
 
1400
    addShare( new Smb4KShare( internal_shares_list.at( i ) ) );
 
1401
  }
 
1402
  
 
1403
  QList<Smb4KShare *> shared_resources = sharedResources( host );
 
1404
  emit shares( host, shared_resources );
 
1405
}
 
1406
 
 
1407
 
 
1408
void Smb4KScanner::slotInfo( Smb4KHost *host )
 
1409
{
 
1410
  Q_ASSERT( host );
 
1411
  
 
1412
  Smb4KHost *known_host = NULL;
 
1413
  
 
1414
  if ( host->infoChecked() )
 
1415
  {
 
1416
    // Copy the information also to host in the global list, if present,
 
1417
    // or copy 'host' to the global list.
 
1418
    known_host = findHost( host->hostName(), host->workgroupName() );
 
1419
 
 
1420
    if ( known_host )
 
1421
    {
 
1422
      known_host->setInfo( host->serverString(), host->osString() );
 
1423
    }
 
1424
    else
 
1425
    {
 
1426
      known_host = new Smb4KHost( *host );
 
1427
      addHost( known_host );
 
1428
    }
 
1429
  }
 
1430
  else
 
1431
  {
 
1432
    // Do nothing
 
1433
  }
 
1434
 
 
1435
  // Emit the host here.
 
1436
  emit info( known_host );
 
1437
}
 
1438
 
 
1439
 
 
1440
#include "smb4kscanner.moc"