File indexing completed on 2024-04-14 15:05:25

0001 /***************************************************************************
0002     This class provides the interface to the libsmbclient library.
0003                              -------------------
0004     begin                : Sa Oct 20 2018
0005     copyright            : (C) 2018-2019 by Alexander Reinholdt
0006     email                : alexander.reinholdt@kdemail.net
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful, but   *
0016  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
0018  *   General Public License for more details.                              *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program; if not, write to the                         *
0022  *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
0023  *   MA 02110-1335, USA                                                    *
0024  ***************************************************************************/
0025 
0026 // application specific includes
0027 #include "smb4kclient.h"
0028 #include "smb4kclient_p.h"
0029 #include "smb4khardwareinterface.h"
0030 #include "smb4ksettings.h"
0031 #include "smb4kcustomoptionsmanager.h"
0032 #include "smb4kcustomoptions.h"
0033 #include "smb4kbasicnetworkitem.h"
0034 #include "smb4kglobal.h"
0035 #include "smb4khomesshareshandler.h"
0036 #include "smb4kwalletmanager.h"
0037 #include "smb4knotification.h"
0038 
0039 // Qt includes
0040 #include <QUdpSocket>
0041 #include <QHostAddress>
0042 #include <QTest>
0043 #include <QApplication>
0044 
0045 using namespace Smb4KGlobal;
0046 
0047 Q_GLOBAL_STATIC(Smb4KClientStatic, p);
0048 
0049 
0050 Smb4KClient::Smb4KClient(QObject* parent) 
0051 : KCompositeJob(parent), d(new Smb4KClientPrivate)
0052 {
0053   //
0054   // Connections
0055   // 
0056   connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit()));
0057 }
0058 
0059 
0060 Smb4KClient::~Smb4KClient()
0061 {
0062 }
0063 
0064 
0065 Smb4KClient *Smb4KClient::self()
0066 {
0067   return &p->instance;
0068 }
0069 
0070 
0071 void Smb4KClient::start()
0072 {
0073   connect(Smb4KHardwareInterface::self(), SIGNAL(networkSessionInitialized()), this, SLOT(slotStartJobs()));
0074 }
0075 
0076 
0077 bool Smb4KClient::isRunning()
0078 {
0079   return hasSubjobs();
0080 }
0081 
0082 
0083 void Smb4KClient::abort()
0084 {
0085   QListIterator<KJob *> it(subjobs());
0086     
0087   while (it.hasNext())
0088   {
0089     it.next()->kill(KJob::EmitResult);
0090   }
0091 }
0092 
0093 
0094 void Smb4KClient::lookupDomains()
0095 {
0096   //
0097   // Send Wakeup-On-LAN packages
0098   // 
0099   if (Smb4KSettings::enableWakeOnLAN())
0100   {
0101     QList<OptionsPtr> wakeOnLanEntries = Smb4KCustomOptionsManager::self()->wakeOnLanEntries();
0102     
0103     if (!wakeOnLanEntries.isEmpty())
0104     {
0105       NetworkItemPtr item = NetworkItemPtr(new Smb4KBasicNetworkItem());
0106       emit aboutToStart(item, WakeUp);
0107       
0108       QUdpSocket *socket = new QUdpSocket(this);
0109       
0110       for (int i = 0; i < wakeOnLanEntries.size(); ++i)
0111       {
0112         if (wakeOnLanEntries.at(i)->wolSendBeforeNetworkScan())
0113         {
0114           QHostAddress addr;
0115           
0116           if (wakeOnLanEntries.at(i)->hasIpAddress())
0117           {
0118             addr.setAddress(wakeOnLanEntries.at(i)->ipAddress());
0119           }
0120           else
0121           {
0122             addr.setAddress("255.255.255.255");
0123           }
0124           
0125           // Construct magic sequence
0126           QByteArray sequence;
0127 
0128           // 6 times 0xFF
0129           for (int j = 0; j < 6; ++j)
0130           {
0131             sequence.append(QChar(0xFF).toLatin1());
0132           }
0133           
0134           // 16 times the MAC address
0135           QStringList parts = wakeOnLanEntries.at(i)->macAddress().split(':', QString::SkipEmptyParts);
0136           
0137           for (int j = 0; j < 16; ++j)
0138           {
0139             for (int k = 0; k < parts.size(); ++k)
0140             {
0141               sequence.append(QChar(QString("0x%1").arg(parts.at(k)).toInt(0, 16)).toLatin1());
0142             }
0143           }
0144           
0145           socket->writeDatagram(sequence, addr, 9);
0146         }
0147       }
0148       
0149       delete socket;
0150       
0151       // Wait the defined time
0152       int stop = 1000 * Smb4KSettings::wakeOnLANWaitingTime() / 250;
0153       int i = 0;
0154       
0155       while (i++ < stop)
0156       {
0157         QTest::qWait(250);
0158       }
0159       
0160       emit finished(item, WakeUp);
0161       item.clear();
0162     }
0163   }
0164   
0165   //
0166   // Emit the aboutToStart() signal
0167   // 
0168   NetworkItemPtr item = NetworkItemPtr(new Smb4KBasicNetworkItem(Network));
0169   item->setUrl(QUrl("smb://"));
0170   emit aboutToStart(item, LookupDomains);
0171   
0172   // 
0173   // Create the job
0174   // 
0175   Smb4KClientJob *job = new Smb4KClientJob(this);
0176   job->setNetworkItem(item);
0177   job->setProcess(LookupDomains);
0178   
0179   //
0180   // Clear the pointer
0181   // 
0182   item.clear();
0183   
0184   //
0185   // Set the busy cursor
0186   //
0187   if (!hasSubjobs() && modifyCursor())
0188   {
0189     QApplication::setOverrideCursor(Qt::BusyCursor);
0190   }
0191 
0192   //
0193   // Add the job to the subjobs
0194   //
0195   addSubjob(job);
0196 
0197   //
0198   // Start the job
0199   // 
0200   job->start();
0201 }
0202 
0203 
0204 void Smb4KClient::lookupDomainMembers(const WorkgroupPtr &workgroup)
0205 {
0206   //
0207   // Emit the aboutToStart() signal
0208   // 
0209   emit aboutToStart(workgroup, LookupDomainMembers);
0210   
0211   // 
0212   // Create the job
0213   // 
0214   Smb4KClientJob *job = new Smb4KClientJob(this);
0215   job->setNetworkItem(workgroup);
0216   job->setProcess(LookupDomainMembers);
0217   
0218   //
0219   // Set the busy cursor
0220   //
0221   if (!hasSubjobs() && modifyCursor())
0222   {
0223     QApplication::setOverrideCursor(Qt::BusyCursor);
0224   }
0225 
0226   //
0227   // Add the job to the subjobs
0228   //
0229   addSubjob(job);
0230 
0231   //
0232   // Start the job
0233   // 
0234   job->start();
0235 }
0236 
0237 
0238 void Smb4KClient::lookupShares(const HostPtr &host)
0239 {
0240   //
0241   // Emit the aboutToStart() signal
0242   // 
0243   emit aboutToStart(host, LookupShares);
0244   
0245   // 
0246   // Create the job
0247   // 
0248   Smb4KClientJob *job = new Smb4KClientJob(this);
0249   job->setNetworkItem(host);
0250   job->setProcess(LookupShares);
0251   
0252   //
0253   // Set the busy cursor
0254   //
0255   if (!hasSubjobs() && modifyCursor())
0256   {
0257     QApplication::setOverrideCursor(Qt::BusyCursor);
0258   }
0259 
0260   //
0261   // Add the job to the subjobs
0262   //
0263   addSubjob(job);
0264 
0265   //
0266   // Start the job
0267   // 
0268   job->start();  
0269 }
0270 
0271 
0272 void Smb4KClient::lookupFiles(const NetworkItemPtr &item)
0273 {
0274   //
0275   // Check that the network item has the correct type and process it.
0276   // 
0277   if (item->type() == Share || item->type() == Directory)
0278   {
0279     //
0280     // Emit the aboutToStart() signal
0281     // 
0282     emit aboutToStart(item, LookupFiles);
0283     
0284     // 
0285     // Create the job
0286     // 
0287     Smb4KClientJob *job = new Smb4KClientJob(this);
0288     job->setNetworkItem(item);
0289     job->setProcess(LookupFiles);
0290     
0291     //
0292     // Set the busy cursor
0293     //
0294     if (!hasSubjobs() && modifyCursor())
0295     {
0296       QApplication::setOverrideCursor(Qt::BusyCursor);
0297     }
0298 
0299     //
0300     // Add the job to the subjobs
0301     //
0302     addSubjob(job);
0303 
0304     //
0305     // Start the job
0306     // 
0307     job->start();
0308   }
0309 }
0310 
0311 
0312 void Smb4KClient::printFile(const SharePtr& share, const KFileItem& fileItem, int copies)
0313 {
0314   //
0315   // Emit the aboutToStart() signal
0316   // 
0317   emit aboutToStart(share, PrintFile);
0318   
0319   // 
0320   // Create the job
0321   // 
0322   Smb4KClientJob *job = new Smb4KClientJob(this);
0323   job->setNetworkItem(share);
0324   job->setPrintFileItem(fileItem);
0325   job->setPrintCopies(copies);
0326   job->setProcess(PrintFile);
0327   
0328   //
0329   // Set the busy cursor
0330   //
0331   if (!hasSubjobs() && modifyCursor())
0332   {
0333     QApplication::setOverrideCursor(Qt::BusyCursor);
0334   }
0335 
0336   //
0337   // Add the job to the subjobs
0338   //
0339   addSubjob(job);
0340 
0341   //
0342   // Start the job
0343   // 
0344   job->start();
0345 }
0346 
0347 
0348 void Smb4KClient::search(const QString& item)
0349 {
0350   //
0351   // Create empty basic network item
0352   // 
0353   NetworkItemPtr networkItem = NetworkItemPtr(new Smb4KBasicNetworkItem());
0354   
0355   //
0356   // Emit the aboutToStart() signal
0357   // 
0358   emit aboutToStart(networkItem, NetworkSearch);
0359   
0360   //
0361   // Before doing the search, lookup all domains, servers and shares in the 
0362   // network neighborhood.
0363   // 
0364   lookupDomains();
0365   
0366   while(isRunning())
0367   {
0368     QTest::qWait(50);
0369   }
0370   
0371   for (const WorkgroupPtr &workgroup : workgroupsList())
0372   {
0373     lookupDomainMembers(workgroup);
0374     
0375     while(isRunning())
0376     {
0377       QTest::qWait(50);
0378     }
0379   }
0380   
0381   for (const HostPtr &host : hostsList())
0382   {
0383     lookupShares(host);
0384     
0385     while(isRunning())
0386     {
0387       QTest::qWait(50);
0388     }
0389   }
0390   
0391   //
0392   // Do the actual search
0393   // 
0394   QList<SharePtr> results;
0395   
0396   for (const SharePtr &share : sharesList())
0397   {
0398     if (share->shareName().contains(item, Qt::CaseInsensitive))
0399     {
0400       results << share;
0401     }
0402   }
0403   
0404   //
0405   // Emit the search results
0406   // 
0407   emit searchResults(results);
0408   
0409   //
0410   // Emit the finished() signal
0411   // 
0412   emit finished(networkItem, NetworkSearch);
0413 }
0414 
0415 
0416 
0417 void Smb4KClient::openPreviewDialog(const SharePtr &share)
0418 {
0419   //
0420   // Printer share check
0421   // 
0422   if (share->isPrinter())
0423   {        
0424     return;
0425   }
0426       
0427   //
0428   // 'homes' share check
0429   //
0430   if (share->isHomesShare())
0431   {
0432     Smb4KHomesSharesHandler::self()->specifyUser(share, true);
0433   }
0434     
0435   //
0436   // Start the preview dialog
0437   // 
0438   // First, check if a preview dialog has already been set up for this share 
0439   // and reuse it, if possible.
0440   // 
0441   QPointer<Smb4KPreviewDialog> dlg = 0;
0442   
0443   for (Smb4KPreviewDialog *p : d->previewDialogs)
0444   {
0445     if (share == p->share())
0446     {
0447       dlg = p;
0448     }
0449   }
0450   
0451   //
0452   // If there was no preview dialog present, create a new one
0453   // 
0454   if (!dlg)
0455   {
0456     dlg = new Smb4KPreviewDialog(share, QApplication::activeWindow());
0457     d->previewDialogs << dlg;
0458     
0459     //
0460     // Connections
0461     // 
0462     connect(dlg, SIGNAL(requestPreview(NetworkItemPtr)), this, SLOT(slotStartNetworkQuery(NetworkItemPtr)));
0463     connect(dlg, SIGNAL(aboutToClose(Smb4KPreviewDialog*)), this, SLOT(slotPreviewDialogClosed(Smb4KPreviewDialog*)));
0464     connect(dlg, SIGNAL(requestAbort()), this, SLOT(slotAbort()));
0465     connect(this, SIGNAL(files(QList<FilePtr>)), dlg, SLOT(slotPreviewResults(QList<FilePtr>)));
0466     connect(this, SIGNAL(aboutToStart(NetworkItemPtr,int)), dlg, SLOT(slotAboutToStart(NetworkItemPtr,int)));
0467     connect(this, SIGNAL(finished(NetworkItemPtr,int)), dlg, SLOT(slotFinished(NetworkItemPtr,int)));
0468   }
0469   
0470   //
0471   // Show the preview dialog
0472   // 
0473   if (!dlg->isVisible())
0474   {
0475     dlg->setVisible(true);
0476   }
0477 }
0478 
0479 
0480 void Smb4KClient::openPrintDialog(const SharePtr& share)
0481 {
0482   //
0483   // Printer share check
0484   // 
0485   if (!share->isPrinter())
0486   {        
0487     return;
0488   }
0489   
0490   //
0491   // Start the print dialog
0492   // 
0493   // First, check if a print dialog has already been set up for this share 
0494   // and reuse it, if possible.
0495   // 
0496   QPointer<Smb4KPrintDialog> dlg = 0;
0497   
0498   for (Smb4KPrintDialog *p : d->printDialogs)
0499   {
0500     if (share == p->share())
0501     {
0502       dlg = p;
0503     }
0504   }
0505   
0506   //
0507   // If there was no print dialog present, create a new one
0508   // 
0509   if (!dlg)
0510   {
0511     Smb4KWalletManager::self()->readAuthInfo(share);
0512     
0513     dlg = new Smb4KPrintDialog(share, QApplication::activeWindow());
0514     d->printDialogs << dlg;
0515     
0516     connect(dlg, SIGNAL(printFile(SharePtr,KFileItem,int)), this, SLOT(slotStartPrinting(SharePtr,KFileItem,int)));
0517     connect(dlg, SIGNAL(aboutToClose(Smb4KPrintDialog*)), this, SLOT(slotPrintDialogClosed(Smb4KPrintDialog*)));
0518   }
0519   
0520   //
0521   // Show the preview dialog
0522   // 
0523   if (!dlg->isVisible())
0524   {
0525     dlg->setVisible(true);
0526   }
0527 }
0528 
0529 
0530 void Smb4KClient::processErrors(Smb4KClientJob *job)
0531 {
0532   switch (job->error())
0533   {
0534     case Smb4KClientJob::AccessDeniedError:
0535     {
0536       switch (job->networkItem()->type())
0537       {
0538         case Host:
0539         {
0540           if (Smb4KWalletManager::self()->showPasswordDialog(job->networkItem()))
0541           {
0542             lookupShares(job->networkItem().staticCast<Smb4KHost>());
0543           }
0544           
0545           break;
0546         }
0547         case Share:
0548         {
0549           if (Smb4KWalletManager::self()->showPasswordDialog(job->networkItem()))
0550           {
0551             if (job->process() == Smb4KGlobal::PrintFile)
0552             {
0553               printFile(job->networkItem().staticCast<Smb4KShare>(), job->printFileItem(), job->printCopies());
0554             }
0555             else
0556             {
0557               lookupFiles(job->networkItem().staticCast<Smb4KShare>());
0558             }
0559           }
0560           
0561           break;
0562         }
0563         case Directory:
0564         case File:
0565         {
0566           FilePtr file = job->networkItem().staticCast<Smb4KFile>();
0567           
0568           SharePtr share = SharePtr(new Smb4KShare());
0569           share->setWorkgroupName(file->workgroupName());
0570           share->setHostName(file->hostName());
0571           share->setShareName(file->shareName());
0572           share->setLogin(file->login());
0573           share->setPassword(file->password());
0574           
0575           if (Smb4KWalletManager::self()->showPasswordDialog(share))
0576           {
0577             file->setLogin(share->login());
0578             file->setPassword(share->password());
0579             
0580             lookupFiles(file);
0581           }
0582 
0583           break;
0584         }
0585         default:
0586         {
0587           qDebug() << "Authentication error. URL:" << job->networkItem()->url();
0588           break;
0589         }
0590       }
0591       
0592       break;
0593     }
0594     default:
0595     {
0596       Smb4KNotification::networkCommunicationFailed(job->errorText());
0597       break;
0598     }
0599   }
0600 }
0601 
0602 
0603 void Smb4KClient::processWorkgroups(Smb4KClientJob *job)
0604 {
0605   //
0606   // Remove obsolete workgroups and their members
0607   //
0608   QListIterator<WorkgroupPtr> wIt(workgroupsList());
0609   
0610   while (wIt.hasNext())
0611   {
0612     WorkgroupPtr workgroup = wIt.next();
0613     
0614     bool found = false;
0615     
0616     for (const WorkgroupPtr &w : job->workgroups())
0617     {
0618       if (w->workgroupName() == workgroup->workgroupName())
0619       {
0620         found = true;
0621         break;
0622       }
0623       else
0624       {
0625         continue;
0626       }        
0627     }
0628     
0629     if (!found)
0630     {
0631       QList<HostPtr> obsoleteHosts = workgroupMembers(workgroup);
0632       QListIterator<HostPtr> hIt(obsoleteHosts);
0633       
0634       while (hIt.hasNext())
0635       {
0636         removeHost(hIt.next());
0637       }
0638       
0639       removeWorkgroup(workgroup);
0640     }
0641   }
0642   
0643   //
0644   // Add new workgroups and update existing ones.
0645   // 
0646   for (const WorkgroupPtr &workgroup : job->workgroups())
0647   {
0648     if (!findWorkgroup(workgroup->workgroupName()))
0649     {
0650       addWorkgroup(workgroup);
0651       
0652       // Since this is a new workgroup, no master browser is present.
0653       HostPtr masterBrowser = HostPtr(new Smb4KHost());
0654       masterBrowser->setWorkgroupName(workgroup->workgroupName());
0655       masterBrowser->setHostName(workgroup->masterBrowserName());
0656       masterBrowser->setIpAddress(workgroup->masterBrowserIpAddress());
0657       masterBrowser->setIsMasterBrowser(true);
0658       
0659       addHost(masterBrowser);
0660     }
0661     else
0662     {
0663       updateWorkgroup(workgroup);
0664       
0665       // Check if the master browser changed
0666       QList<HostPtr> members = workgroupMembers(workgroup);
0667       
0668       for (const HostPtr &host : members)
0669       {
0670         if (workgroup->masterBrowserName() == host->hostName())
0671         {
0672           host->setIsMasterBrowser(true);
0673           
0674           if (!host->hasIpAddress() && workgroup->hasMasterBrowserIpAddress())
0675           {
0676             host->setIpAddress(workgroup->masterBrowserIpAddress());
0677           }
0678         }
0679         else
0680         {
0681           host->setIsMasterBrowser(false);
0682         }
0683       }
0684     }
0685   }
0686   
0687   emit workgroups();
0688 }
0689 
0690 
0691 void Smb4KClient::processHosts(Smb4KClientJob *job)
0692 {
0693   // 
0694   // Get the workgroup pointer
0695   // 
0696   WorkgroupPtr workgroup = job->networkItem().staticCast<Smb4KWorkgroup>();
0697 
0698   //
0699   // Remove obsolete workgroup members
0700   // 
0701   QList<HostPtr> members = workgroupMembers(workgroup);
0702   QListIterator<HostPtr> hIt(members);
0703     
0704   while (hIt.hasNext())
0705   {
0706     HostPtr host = hIt.next();
0707       
0708     bool found = false;
0709       
0710     for (const HostPtr &h : job->hosts())
0711     {
0712       if (h->workgroupName() == host->workgroupName() && h->hostName() == host->hostName())
0713       {
0714         found = true;
0715         break;
0716       }
0717       else
0718       {
0719         continue;
0720       }        
0721     }
0722       
0723     if (!found)
0724     {
0725       QList<SharePtr> obsoleteShares = sharedResources(host);
0726       QListIterator<SharePtr> sIt(obsoleteShares);
0727         
0728       while (sIt.hasNext())
0729       {
0730         removeShare(sIt.next());
0731       }
0732         
0733       removeHost(host);
0734     }
0735   }
0736     
0737   //
0738   // Add new hosts and update existing ones
0739   //
0740   for (const HostPtr &host : job->hosts())
0741   {
0742     if (host->hostName() == workgroup->masterBrowserName())
0743     {
0744       host->setIsMasterBrowser(true);
0745     }
0746     else
0747     {
0748       host->setIsMasterBrowser(false);
0749     }
0750       
0751     if (!findHost(host->hostName(), host->workgroupName()))
0752     {
0753       addHost(host);
0754     }
0755     else
0756     {
0757       updateHost(host);
0758     }
0759   }
0760     
0761   emit hosts(workgroup);
0762 }
0763 
0764 
0765 void Smb4KClient::processShares(Smb4KClientJob *job)
0766 {
0767   //
0768   // Get the host pointer
0769   // 
0770   HostPtr host = job->networkItem().staticCast<Smb4KHost>();
0771 
0772   //
0773   // Remove obsolete shares
0774   //
0775   QList<SharePtr> sharedRes = sharedResources(host);
0776   QListIterator<SharePtr> sIt(sharedRes);
0777     
0778   while (sIt.hasNext())
0779   {
0780     SharePtr share = sIt.next();
0781       
0782     bool found = false;
0783       
0784     for (const SharePtr &s : job->shares())
0785     {
0786       if (s->workgroupName() == share->workgroupName() && s->url().matches(share->url(), QUrl::RemoveUserInfo|QUrl::RemovePort))
0787       {
0788         found = true;
0789         break;
0790       }
0791       else
0792       {
0793         continue;
0794       }
0795     }
0796       
0797     if (!found || (share->isHidden() && !Smb4KSettings::detectHiddenShares()) || (share->isPrinter() && !Smb4KSettings::detectPrinterShares()))
0798     {
0799       removeShare(share);
0800     }
0801   }
0802   
0803   //
0804   // Add new shares and update existing ones
0805   //
0806   for (const SharePtr &share : job->shares())
0807   {
0808     //
0809     // Process only those shares that the user wants to see
0810     //
0811     if (share->isHidden() && !Smb4KSettings::detectHiddenShares())
0812     {
0813       continue;
0814     }
0815       
0816     if (share->isPrinter() && !Smb4KSettings::detectPrinterShares())
0817     {
0818       continue;
0819     }
0820       
0821     //
0822     // Add or update the shares
0823     //
0824     if (!findShare(share->url(), share->workgroupName()))
0825     {
0826       addShare(share);
0827     }
0828     else
0829     {
0830       updateShare(share);
0831     }
0832   }
0833     
0834   emit shares(host);
0835 }
0836 
0837 
0838 void Smb4KClient::processFiles(Smb4KClientJob *job)
0839 {
0840   QList<FilePtr> list;
0841   
0842   for (const FilePtr &f : job->files())
0843   {
0844     if (f->isHidden() && !Smb4KSettings::previewHiddenItems())
0845     {
0846       continue;
0847     }
0848     
0849     list << f;
0850   }  
0851   
0852   emit files(list);
0853 }
0854 
0855 
0856 void Smb4KClient::slotStartJobs()
0857 {
0858   //
0859   // Disconnect from Smb4KHardwareInterface
0860   //
0861   disconnect(Smb4KHardwareInterface::self(), SIGNAL(networkSessionInitialized()), this, SLOT(slotStartJobs()));
0862 
0863   //
0864   // Lookup domains as the first step
0865   // 
0866   if (Smb4KHardwareInterface::self()->isOnline())
0867   {
0868     lookupDomains();
0869   }
0870 }
0871 
0872 
0873 void Smb4KClient::slotResult(KJob *job)
0874 {
0875   //
0876   // Get the client job
0877   // 
0878   Smb4KClientJob *clientJob = qobject_cast<Smb4KClientJob *>(job);
0879   
0880   //
0881   // Define a network item pointer and the process value for the 
0882   // finished() signal.
0883   // 
0884   NetworkItemPtr item = clientJob->networkItem();
0885   Smb4KGlobal::Process process = clientJob->process();
0886   
0887   //
0888   // Get the result from the query and process it
0889   // 
0890   if (clientJob)
0891   {
0892     if (clientJob->error() == 0)
0893     {
0894       switch (clientJob->networkItem()->type())
0895       {
0896         case Network:
0897         {
0898           // Process the discovered workgroups
0899           processWorkgroups(clientJob);
0900           break;
0901         }
0902         case Workgroup:
0903         {
0904           // Process the discovered workgroup members
0905           processHosts(clientJob);
0906           break;
0907         }
0908         case Host:
0909         {
0910           // Process the discovered shares
0911           processShares(clientJob);
0912           break;
0913         }
0914         case Share:
0915         case Directory:
0916         {
0917           // Process the discoveres files and directories
0918           processFiles(clientJob);
0919           break;
0920         }
0921         default:
0922         {
0923           break;
0924         }
0925       }
0926     }
0927     else
0928     {
0929       processErrors(clientJob);
0930     }
0931   }
0932 
0933   //
0934   // Remove the job
0935   //
0936   removeSubjob(job);
0937   
0938   //
0939   // Emit the finished signal
0940   // 
0941   finished(item, process);
0942   
0943   //
0944   // Clear the network item pointer
0945   // 
0946   item.clear();
0947   
0948   //
0949   // Restore the cursor
0950   //
0951   if (!hasSubjobs() && modifyCursor())
0952   {
0953     QApplication::restoreOverrideCursor();
0954   }
0955 }
0956 
0957 
0958 void Smb4KClient::slotAboutToQuit()
0959 {
0960   abort();
0961 }
0962 
0963 
0964 void Smb4KClient::slotStartNetworkQuery(NetworkItemPtr item)
0965 {
0966   //
0967   // Look up files
0968   //
0969   lookupFiles(item);
0970 }
0971 
0972 
0973 void Smb4KClient::slotPreviewDialogClosed(Smb4KPreviewDialog *dialog)
0974 {
0975   //
0976   // Remove the preview dialog from the list
0977   // 
0978   if (dialog)
0979   {
0980     // Find the dialog in the list and take it from the list.
0981     // It will automatically be deleted on close, so there is
0982     // no need to delete the dialog here.
0983     int i = d->previewDialogs.indexOf(dialog);
0984     d->previewDialogs.takeAt(i);
0985   }
0986 }
0987 
0988 
0989 void Smb4KClient::slotAbort()
0990 {
0991   abort();
0992 }
0993 
0994 
0995 void Smb4KClient::slotStartPrinting(const SharePtr& printer, const KFileItem& fileItem, int copies)
0996 {
0997   //
0998   // Start printing
0999   // 
1000   printFile(printer, fileItem, copies);
1001 }
1002 
1003 
1004 void Smb4KClient::slotPrintDialogClosed(Smb4KPrintDialog* dialog)
1005 {
1006   //
1007   // Remove the print dialog from the list
1008   // 
1009   if (dialog)
1010   {
1011     // Find the dialog in the list and take it from the list.
1012     // It will automatically be deleted on close, so there is
1013     // no need to delete the dialog here.
1014     int i = d->printDialogs.indexOf(dialog);
1015     d->printDialogs.takeAt(i);
1016   }
1017 }
1018 
1019 
1020 
1021 
1022