File indexing completed on 2024-04-21 05:01:36
0001 /* 0002 This class provides the interface to the libsmbclient library. 0003 0004 SPDX-FileCopyrightText: 2018-2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4kclient.h" 0010 #include "smb4kbasicnetworkitem.h" 0011 #include "smb4kclient_p.h" 0012 #include "smb4kcustomsettings.h" 0013 #include "smb4kcustomsettingsmanager.h" 0014 #include "smb4khardwareinterface.h" 0015 #include "smb4khomesshareshandler.h" 0016 #include "smb4knotification.h" 0017 #include "smb4ksettings.h" 0018 #include "smb4kwalletmanager.h" 0019 0020 // Qt includes 0021 #include <QApplication> 0022 #include <QHostAddress> 0023 #include <QPointer> 0024 #include <QTimer> 0025 #include <QUdpSocket> 0026 0027 using namespace Smb4KGlobal; 0028 0029 Q_GLOBAL_STATIC(Smb4KClientStatic, p); 0030 0031 Smb4KClient::Smb4KClient(QObject *parent) 0032 : KCompositeJob(parent) 0033 , d(new Smb4KClientPrivate) 0034 { 0035 connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &Smb4KClient::slotAboutToQuit); 0036 connect(Smb4KWalletManager::self(), &Smb4KWalletManager::credentialsUpdated, this, &Smb4KClient::slotCredentialsUpdated); 0037 } 0038 0039 Smb4KClient::~Smb4KClient() 0040 { 0041 } 0042 0043 Smb4KClient *Smb4KClient::self() 0044 { 0045 return &p->instance; 0046 } 0047 0048 void Smb4KClient::start() 0049 { 0050 // 0051 // Connect to the online state monitoring 0052 // 0053 connect(Smb4KHardwareInterface::self(), &Smb4KHardwareInterface::onlineStateChanged, this, &Smb4KClient::slotOnlineStateChanged, Qt::UniqueConnection); 0054 0055 // 0056 // Start the scanning 0057 // 0058 if (Smb4KHardwareInterface::self()->isOnline()) { 0059 QTimer::singleShot(50, this, SLOT(slotStartJobs())); 0060 } 0061 } 0062 0063 bool Smb4KClient::isRunning() 0064 { 0065 return hasSubjobs(); 0066 } 0067 0068 void Smb4KClient::abort() 0069 { 0070 QListIterator<KJob *> it(subjobs()); 0071 0072 while (it.hasNext()) { 0073 it.next()->kill(KJob::EmitResult); 0074 } 0075 } 0076 0077 void Smb4KClient::lookupDomains() 0078 { 0079 // 0080 // Send Wakeup-On-LAN packets 0081 // 0082 if (Smb4KSettings::enableWakeOnLAN()) { 0083 QList<CustomSettingsPtr> wakeOnLanEntries = Smb4KCustomSettingsManager::self()->wakeOnLanEntries(); 0084 0085 if (!wakeOnLanEntries.isEmpty()) { 0086 NetworkItemPtr item = NetworkItemPtr(new Smb4KBasicNetworkItem()); 0087 Q_EMIT aboutToStart(item, WakeUp); 0088 0089 QUdpSocket *socket = new QUdpSocket(this); 0090 0091 for (int i = 0; i < wakeOnLanEntries.size(); ++i) { 0092 if (wakeOnLanEntries.at(i)->wakeOnLanSendBeforeNetworkScan()) { 0093 QHostAddress addr; 0094 0095 if (wakeOnLanEntries.at(i)->hasIpAddress()) { 0096 addr.setAddress(wakeOnLanEntries.at(i)->ipAddress()); 0097 } else { 0098 addr.setAddress(QStringLiteral("255.255.255.255")); 0099 } 0100 0101 // Construct magic sequence 0102 QByteArray sequence; 0103 0104 // 6 times 0xFF 0105 for (int j = 0; j < 6; ++j) { 0106 sequence.append(QChar(0xFF).toLatin1()); 0107 } 0108 0109 // 16 times the MAC address 0110 QStringList parts = wakeOnLanEntries.at(i)->macAddress().split(QStringLiteral(":"), Qt::SkipEmptyParts); 0111 0112 for (int j = 0; j < 16; ++j) { 0113 for (int k = 0; k < parts.size(); ++k) { 0114 QString item = QStringLiteral("0x") + parts.at(k); 0115 sequence.append(QChar(item.toInt(nullptr, 16)).toLatin1()); 0116 } 0117 } 0118 0119 socket->writeDatagram(sequence, addr, 9); 0120 } 0121 } 0122 0123 delete socket; 0124 0125 // Wait the defined time 0126 int stop = 1000 * Smb4KSettings::wakeOnLANWaitingTime() / 250; 0127 int i = 0; 0128 0129 while (i++ < stop) { 0130 wait(250); 0131 } 0132 0133 Q_EMIT finished(item, WakeUp); 0134 item.clear(); 0135 } 0136 } 0137 0138 // 0139 // Emit the aboutToStart() signal 0140 // 0141 NetworkItemPtr networkItem = NetworkItemPtr(new Smb4KBasicNetworkItem(Network)); 0142 networkItem->setUrl(QUrl(QStringLiteral("smb://"))); 0143 Q_EMIT aboutToStart(networkItem, LookupDomains); 0144 0145 // 0146 // Set the busy cursor 0147 // 0148 if (!hasSubjobs()) { 0149 QApplication::setOverrideCursor(Qt::BusyCursor); 0150 } 0151 0152 // 0153 // Create the client job 0154 // 0155 Smb4KClientJob *clientJob = new Smb4KClientJob(this); 0156 clientJob->setNetworkItem(networkItem); 0157 clientJob->setProcess(LookupDomains); 0158 0159 #ifdef USE_WS_DISCOVERY 0160 // 0161 // Create the WS Discovery job, if desired 0162 // 0163 Smb4KWsDiscoveryJob *wsDiscoveryJob = nullptr; 0164 0165 if (Smb4KSettings::useWsDiscovery()) { 0166 wsDiscoveryJob = new Smb4KWsDiscoveryJob(this); 0167 wsDiscoveryJob->setNetworkItem(networkItem); 0168 wsDiscoveryJob->setProcess(LookupDomains); 0169 } 0170 #endif 0171 0172 // 0173 // Create the DNS-SD job, if desired 0174 // 0175 Smb4KDnsDiscoveryJob *dnsDiscoveryJob = nullptr; 0176 0177 if (Smb4KSettings::useDnsServiceDiscovery()) { 0178 dnsDiscoveryJob = new Smb4KDnsDiscoveryJob(this); 0179 dnsDiscoveryJob->setNetworkItem(networkItem); 0180 dnsDiscoveryJob->setProcess(LookupDomains); 0181 } 0182 0183 // 0184 // Add the jobs to the subjobs 0185 // 0186 addSubjob(clientJob); 0187 0188 #ifdef USE_WS_DISCOVERY 0189 if (wsDiscoveryJob) { 0190 addSubjob(wsDiscoveryJob); 0191 } 0192 #endif 0193 0194 if (dnsDiscoveryJob) { 0195 addSubjob(dnsDiscoveryJob); 0196 } 0197 0198 // 0199 // Start the jobs 0200 // 0201 clientJob->start(); 0202 0203 #ifdef USE_WS_DISCOVERY 0204 if (wsDiscoveryJob) { 0205 wsDiscoveryJob->start(); 0206 } 0207 #endif 0208 0209 if (dnsDiscoveryJob) { 0210 dnsDiscoveryJob->start(); 0211 } 0212 0213 // 0214 // Clear the network item 0215 // 0216 networkItem.clear(); 0217 } 0218 0219 void Smb4KClient::lookupDomainMembers(const WorkgroupPtr &workgroup) 0220 { 0221 // 0222 // Emit the aboutToStart() signal 0223 // 0224 Q_EMIT aboutToStart(workgroup, LookupDomainMembers); 0225 0226 // 0227 // Set the busy cursor 0228 // 0229 if (!hasSubjobs()) { 0230 QApplication::setOverrideCursor(Qt::BusyCursor); 0231 } 0232 0233 // 0234 // Create the client job 0235 // 0236 Smb4KClientJob *clientJob = new Smb4KClientJob(this); 0237 clientJob->setNetworkItem(workgroup); 0238 clientJob->setProcess(LookupDomainMembers); 0239 0240 #ifdef USE_WS_DISCOVERY 0241 // 0242 // Create the WS Discovery job, if desired 0243 // 0244 Smb4KWsDiscoveryJob *wsDiscoveryJob = nullptr; 0245 0246 if (Smb4KSettings::useWsDiscovery()) { 0247 wsDiscoveryJob = new Smb4KWsDiscoveryJob(this); 0248 wsDiscoveryJob->setNetworkItem(workgroup); 0249 wsDiscoveryJob->setProcess(LookupDomainMembers); 0250 } 0251 #endif 0252 0253 // 0254 // Create the DNS-SD job, if desired 0255 // 0256 Smb4KDnsDiscoveryJob *dnsDiscoveryJob = nullptr; 0257 0258 if (Smb4KSettings::useDnsServiceDiscovery()) { 0259 dnsDiscoveryJob = new Smb4KDnsDiscoveryJob(this); 0260 dnsDiscoveryJob->setNetworkItem(workgroup); 0261 dnsDiscoveryJob->setProcess(LookupDomainMembers); 0262 } 0263 0264 // 0265 // Add the jobs to the subjobs 0266 // 0267 addSubjob(clientJob); 0268 0269 #ifdef USE_WS_DISCOVERY 0270 if (wsDiscoveryJob) { 0271 addSubjob(wsDiscoveryJob); 0272 } 0273 #endif 0274 0275 if (dnsDiscoveryJob) { 0276 addSubjob(dnsDiscoveryJob); 0277 } 0278 0279 // 0280 // Start the job 0281 // 0282 clientJob->start(); 0283 0284 #ifdef USE_WS_DISCOVERY 0285 if (wsDiscoveryJob) { 0286 wsDiscoveryJob->start(); 0287 } 0288 #endif 0289 0290 if (dnsDiscoveryJob) { 0291 dnsDiscoveryJob->start(); 0292 } 0293 } 0294 0295 void Smb4KClient::lookupShares(const HostPtr &host) 0296 { 0297 // 0298 // Emit the aboutToStart() signal 0299 // 0300 Q_EMIT aboutToStart(host, LookupShares); 0301 0302 // 0303 // Create the job 0304 // 0305 Smb4KClientJob *job = new Smb4KClientJob(this); 0306 job->setNetworkItem(host); 0307 job->setProcess(LookupShares); 0308 0309 // 0310 // Set the busy cursor 0311 // 0312 if (!hasSubjobs()) { 0313 QApplication::setOverrideCursor(Qt::BusyCursor); 0314 } 0315 0316 // 0317 // Add the job to the subjobs 0318 // 0319 addSubjob(job); 0320 0321 // 0322 // Start the job 0323 // 0324 job->start(); 0325 } 0326 0327 void Smb4KClient::lookupFiles(const NetworkItemPtr &item) 0328 { 0329 if (item->type() == Share || (item->type() == FileOrDirectory && item.staticCast<Smb4KFile>()->isDirectory())) { 0330 Q_EMIT aboutToStart(item, LookupFiles); 0331 0332 Smb4KClientJob *job = new Smb4KClientJob(this); 0333 job->setNetworkItem(item); 0334 job->setProcess(LookupFiles); 0335 0336 if (!hasSubjobs()) { 0337 QApplication::setOverrideCursor(Qt::BusyCursor); 0338 } 0339 0340 addSubjob(job); 0341 0342 job->start(); 0343 } 0344 } 0345 0346 void Smb4KClient::printFile(const SharePtr &share, const KFileItem &fileItem, int copies) 0347 { 0348 if (fileItem.mimetype() != QStringLiteral("application/postscript") && fileItem.mimetype() != QStringLiteral("application/pdf") 0349 && fileItem.mimetype() != QStringLiteral("application/x-shellscript") && !fileItem.mimetype().startsWith(QStringLiteral("text")) 0350 && !fileItem.mimetype().startsWith(QStringLiteral("message")) && !fileItem.mimetype().startsWith(QStringLiteral("image"))) { 0351 Smb4KNotification::mimetypeNotSupported(fileItem.mimetype()); 0352 return; 0353 } 0354 0355 // 0356 // Emit the aboutToStart() signal 0357 // 0358 Q_EMIT aboutToStart(share, PrintFile); 0359 0360 // 0361 // Create the job 0362 // 0363 Smb4KClientJob *job = new Smb4KClientJob(this); 0364 job->setNetworkItem(share); 0365 job->setPrintFileItem(fileItem); 0366 job->setPrintCopies(copies); 0367 job->setProcess(PrintFile); 0368 0369 // 0370 // Set the busy cursor 0371 // 0372 if (!hasSubjobs()) { 0373 QApplication::setOverrideCursor(Qt::BusyCursor); 0374 } 0375 0376 // 0377 // Add the job to the subjobs 0378 // 0379 addSubjob(job); 0380 0381 // 0382 // Start the job 0383 // 0384 job->start(); 0385 } 0386 0387 void Smb4KClient::search(const QString &item) 0388 { 0389 // 0390 // Create empty basic network item 0391 // 0392 NetworkItemPtr networkItem = NetworkItemPtr(new Smb4KBasicNetworkItem()); 0393 0394 // 0395 // Emit the aboutToStart() signal 0396 // 0397 Q_EMIT aboutToStart(networkItem, NetworkSearch); 0398 0399 // 0400 // Before doing the search, lookup all domains, servers and shares in the 0401 // network neighborhood. 0402 // 0403 lookupDomains(); 0404 0405 while (isRunning()) { 0406 wait(50); 0407 } 0408 0409 for (const WorkgroupPtr &workgroup : workgroupsList()) { 0410 lookupDomainMembers(workgroup); 0411 0412 while (isRunning()) { 0413 wait(50); 0414 } 0415 } 0416 0417 for (const HostPtr &host : hostsList()) { 0418 lookupShares(host); 0419 0420 while (isRunning()) { 0421 wait(50); 0422 } 0423 } 0424 0425 // 0426 // Do the actual search 0427 // 0428 QList<SharePtr> results; 0429 0430 for (const SharePtr &share : sharesList()) { 0431 if (share->shareName().contains(item, Qt::CaseInsensitive)) { 0432 results << share; 0433 } 0434 } 0435 0436 // 0437 // Emit the search results 0438 // 0439 Q_EMIT searchResults(results); 0440 0441 // 0442 // Emit the finished() signal 0443 // 0444 Q_EMIT finished(networkItem, NetworkSearch); 0445 } 0446 0447 void Smb4KClient::processErrors(Smb4KClientBaseJob *job) 0448 { 0449 switch (job->error()) { 0450 case Smb4KClientJob::AccessDeniedError: { 0451 switch (job->networkItem()->type()) { 0452 case Host: { 0453 Smb4KClientPrivate::QueueContainer container; 0454 container.process = job->process(); 0455 container.networkItem = job->networkItem(); 0456 d->queue.append(container); 0457 Q_EMIT requestCredentials(job->networkItem()); 0458 0459 break; 0460 } 0461 case Share: { 0462 Smb4KClientPrivate::QueueContainer container; 0463 container.process = job->process(); 0464 container.networkItem = job->networkItem(); 0465 0466 if (job->process() == Smb4KGlobal::PrintFile) { 0467 Smb4KClientJob *clientJob = qobject_cast<Smb4KClientJob *>(job); 0468 container.printFileItem = clientJob->printFileItem(); 0469 container.printCopies = clientJob->printCopies(); 0470 } 0471 0472 d->queue.append(container); 0473 Q_EMIT requestCredentials(job->networkItem()); 0474 0475 break; 0476 } 0477 case FileOrDirectory: { 0478 Smb4KClientPrivate::QueueContainer container; 0479 container.process = job->process(); 0480 container.networkItem = job->networkItem(); 0481 d->queue.append(container); 0482 0483 FilePtr file = job->networkItem().staticCast<Smb4KFile>(); 0484 SharePtr share = SharePtr(new Smb4KShare()); 0485 share->setWorkgroupName(file->workgroupName()); 0486 share->setHostName(file->hostName()); 0487 share->setShareName(file->shareName()); 0488 share->setUserName(file->userName()); 0489 share->setPassword(file->password()); 0490 Q_EMIT requestCredentials(share); 0491 0492 break; 0493 } 0494 default: { 0495 qDebug() << "Authentication error. URL:" << job->networkItem()->url(); 0496 break; 0497 } 0498 } 0499 0500 break; 0501 } 0502 default: { 0503 Smb4KNotification::networkCommunicationFailed(job->errorText()); 0504 break; 0505 } 0506 } 0507 } 0508 0509 void Smb4KClient::processWorkgroups(Smb4KClientBaseJob *job) 0510 { 0511 // 0512 // Collect the workgroups found while scanning 0513 // 0514 QList<WorkgroupPtr> discoveredWorkgroups = job->workgroups(); 0515 0516 for (const WorkgroupPtr &newWorkgroup : qAsConst(discoveredWorkgroups)) { 0517 bool foundWorkgroup = false; 0518 0519 for (const WorkgroupPtr &workgroup : qAsConst(d->tempWorkgroupList)) { 0520 if (workgroup->workgroupName() == newWorkgroup->workgroupName()) { 0521 foundWorkgroup = true; 0522 break; 0523 } 0524 } 0525 0526 if (!foundWorkgroup) { 0527 d->tempWorkgroupList << newWorkgroup; 0528 } 0529 } 0530 0531 // 0532 // When scanning finished, process the workgroups 0533 // 0534 if (!isRunning()) { 0535 // Remove obsolete workgroups and their members 0536 QListIterator<WorkgroupPtr> it(workgroupsList()); 0537 0538 while (it.hasNext()) { 0539 WorkgroupPtr workgroup = it.next(); 0540 0541 bool foundWorkgroup = false; 0542 0543 for (const WorkgroupPtr &w : qAsConst(d->tempWorkgroupList)) { 0544 if (w->workgroupName() == workgroup->workgroupName()) { 0545 foundWorkgroup = true; 0546 break; 0547 } 0548 } 0549 0550 if (!foundWorkgroup) { 0551 QList<HostPtr> obsoleteHosts = workgroupMembers(workgroup); 0552 0553 while (!obsoleteHosts.isEmpty()) { 0554 removeHost(obsoleteHosts.takeFirst()); 0555 } 0556 0557 removeWorkgroup(workgroup); 0558 } 0559 } 0560 0561 // Add new workgroups and update existing ones 0562 for (const WorkgroupPtr &workgroup : qAsConst(d->tempWorkgroupList)) { 0563 if (!findWorkgroup(workgroup->workgroupName())) { 0564 addWorkgroup(workgroup); 0565 0566 // Since this is a new workgroup, no master browser is present. 0567 HostPtr masterBrowser = HostPtr(new Smb4KHost()); 0568 masterBrowser->setWorkgroupName(workgroup->workgroupName()); 0569 masterBrowser->setHostName(workgroup->masterBrowserName()); 0570 masterBrowser->setIpAddress(workgroup->masterBrowserIpAddress()); 0571 masterBrowser->setIsMasterBrowser(true); 0572 0573 addHost(masterBrowser); 0574 } else { 0575 updateWorkgroup(workgroup); 0576 0577 // Check if the master browser changed 0578 QList<HostPtr> members = workgroupMembers(workgroup); 0579 0580 for (const HostPtr &host : qAsConst(members)) { 0581 if (workgroup->masterBrowserName() == host->hostName()) { 0582 host->setIsMasterBrowser(true); 0583 0584 if (!host->hasIpAddress() && workgroup->hasMasterBrowserIpAddress()) { 0585 host->setIpAddress(workgroup->masterBrowserIpAddress()); 0586 } 0587 } else { 0588 host->setIsMasterBrowser(false); 0589 } 0590 } 0591 } 0592 } 0593 0594 // Clear the temporary workgroup list 0595 while (!d->tempWorkgroupList.isEmpty()) { 0596 d->tempWorkgroupList.takeFirst().clear(); 0597 } 0598 0599 Q_EMIT workgroups(); 0600 } 0601 } 0602 0603 void Smb4KClient::processHosts(Smb4KClientBaseJob *job) 0604 { 0605 // 0606 // Collect the hosts found while scanning. Always prefer 0607 // insertion of hosts with a real workgroup/domain over 0608 // the ones with the DNS-SD domain (e.g. LOCAL). 0609 // 0610 QList<HostPtr> discoveredHosts = job->hosts(); 0611 0612 for (const HostPtr &newHost : qAsConst(discoveredHosts)) { 0613 bool foundHost = false; 0614 0615 QMutableListIterator<HostPtr> it(d->tempHostList); 0616 0617 while (it.hasNext()) { 0618 HostPtr host = static_cast<HostPtr>(it.next()); 0619 0620 if (newHost->url().matches(host->url(), QUrl::RemoveUserInfo | QUrl::RemovePort)) { 0621 if (newHost->workgroupName() == host->workgroupName()) { 0622 foundHost = true; 0623 } else if (host->dnsDiscovered()) { 0624 it.remove(); 0625 } 0626 0627 break; 0628 } 0629 } 0630 0631 if (!foundHost) { 0632 d->tempHostList << newHost; 0633 } 0634 } 0635 0636 // 0637 // When scanning finished, process the hosts 0638 // 0639 if (!isRunning()) { 0640 // Get the workgroup pointer. Although several scans might have been 0641 // running, the workgroup should have been always the same. 0642 WorkgroupPtr workgroup = job->networkItem().staticCast<Smb4KWorkgroup>(); 0643 0644 // Remove obsolete workgroup/domain members 0645 QList<HostPtr> members = workgroupMembers(workgroup); 0646 QListIterator<HostPtr> it(members); 0647 0648 while (it.hasNext()) { 0649 HostPtr host = it.next(); 0650 0651 bool foundHost = false; 0652 0653 for (const HostPtr &h : qAsConst(d->tempHostList)) { 0654 if (h->workgroupName() == host->workgroupName() && h->hostName() == host->hostName()) { 0655 foundHost = true; 0656 break; 0657 } 0658 } 0659 0660 if (!foundHost) { 0661 QList<SharePtr> obsoleteShares = sharedResources(host); 0662 0663 while (!obsoleteShares.isEmpty()) { 0664 removeShare(obsoleteShares.takeFirst()); 0665 } 0666 0667 removeHost(host); 0668 } 0669 } 0670 0671 // Add new hosts and update existing ones 0672 for (const HostPtr &host : qAsConst(d->tempHostList)) { 0673 if (host->hostName() == workgroup->masterBrowserName()) { 0674 host->setIsMasterBrowser(true); 0675 } else { 0676 host->setIsMasterBrowser(false); 0677 } 0678 0679 if (!findHost(host->hostName(), host->workgroupName())) { 0680 addHost(host); 0681 } else { 0682 updateHost(host); 0683 } 0684 } 0685 0686 // Clear the temporary host list 0687 while (!d->tempHostList.isEmpty()) { 0688 d->tempHostList.takeFirst().clear(); 0689 } 0690 0691 Q_EMIT hosts(workgroup); 0692 } 0693 } 0694 0695 void Smb4KClient::processShares(Smb4KClientBaseJob *job) 0696 { 0697 // 0698 // To look up the shared resources of a host, we only use 0699 // Samba's client library, so we do not have to wait until 0700 // several jobs finished. 0701 // 0702 // Get the host pointer 0703 // 0704 HostPtr host = job->networkItem().staticCast<Smb4KHost>(); 0705 0706 // 0707 // Copy the list of discovered shares 0708 // 0709 QList<SharePtr> discoveredShares = job->shares(); 0710 0711 // 0712 // Remove obsolete shares 0713 // 0714 QList<SharePtr> sharedRes = sharedResources(host); 0715 QListIterator<SharePtr> it(sharedRes); 0716 0717 while (it.hasNext()) { 0718 SharePtr share = it.next(); 0719 0720 bool foundShare = false; 0721 0722 for (const SharePtr &s : qAsConst(discoveredShares)) { 0723 if (s->workgroupName() == share->workgroupName() && s->url().matches(share->url(), QUrl::RemoveUserInfo | QUrl::RemovePort)) { 0724 foundShare = true; 0725 break; 0726 } 0727 } 0728 0729 if (!foundShare || (share->isHidden() && !Smb4KSettings::detectHiddenShares()) || (share->isPrinter() && !Smb4KSettings::detectPrinterShares())) { 0730 removeShare(share); 0731 } 0732 } 0733 0734 // 0735 // Add new shares and update existing ones 0736 // 0737 for (const SharePtr &share : qAsConst(discoveredShares)) { 0738 // Process only those shares that the user wants to see 0739 if (share->isHidden() && !Smb4KSettings::detectHiddenShares()) { 0740 continue; 0741 } 0742 0743 if (share->isPrinter() && !Smb4KSettings::detectPrinterShares()) { 0744 continue; 0745 } 0746 0747 // Add or update the shares 0748 if (!findShare(share->url(), share->workgroupName())) { 0749 addShare(share); 0750 } else { 0751 updateShare(share); 0752 } 0753 } 0754 0755 Q_EMIT shares(host); 0756 } 0757 0758 void Smb4KClient::processFiles(Smb4KClientBaseJob *job) 0759 { 0760 QList<FilePtr> discoveredFiles = job->files(); 0761 QList<FilePtr> list; 0762 0763 for (const FilePtr &file : qAsConst(discoveredFiles)) { 0764 if (file->isHidden() && !Smb4KSettings::previewHiddenItems()) { 0765 continue; 0766 } 0767 0768 list << file; 0769 } 0770 0771 Q_EMIT files(list); 0772 } 0773 0774 void Smb4KClient::slotStartJobs() 0775 { 0776 lookupDomains(); 0777 } 0778 0779 void Smb4KClient::slotOnlineStateChanged(bool online) 0780 { 0781 if (online) { 0782 slotStartJobs(); 0783 } else { 0784 abort(); 0785 } 0786 } 0787 0788 void Smb4KClient::slotResult(KJob *job) 0789 { 0790 // 0791 // Remove the job 0792 // 0793 removeSubjob(job); 0794 0795 // 0796 // Get the client base job 0797 // 0798 Smb4KClientBaseJob *clientBaseJob = qobject_cast<Smb4KClientBaseJob *>(job); 0799 0800 // 0801 // Define a network item pointer and the process value for the 0802 // finished() signal. 0803 // 0804 NetworkItemPtr networkItem = clientBaseJob->networkItem(); 0805 Smb4KGlobal::Process process = clientBaseJob->process(); 0806 0807 // 0808 // Get the result from the query and process it 0809 // 0810 if (clientBaseJob->error() == 0) { 0811 switch (networkItem->type()) { 0812 case Network: { 0813 // Process the discovered workgroups 0814 processWorkgroups(clientBaseJob); 0815 break; 0816 } 0817 case Workgroup: { 0818 // Process the discovered workgroup members 0819 processHosts(clientBaseJob); 0820 break; 0821 } 0822 case Host: { 0823 // Process the discovered shares 0824 processShares(clientBaseJob); 0825 break; 0826 } 0827 case Share: { 0828 processFiles(clientBaseJob); 0829 break; 0830 } 0831 case FileOrDirectory: { 0832 if (networkItem.staticCast<Smb4KFile>()->isDirectory()) { 0833 processFiles(clientBaseJob); 0834 } 0835 break; 0836 } 0837 default: { 0838 break; 0839 } 0840 } 0841 } else { 0842 processErrors(clientBaseJob); 0843 } 0844 0845 // 0846 // Emit the finished signal when all subjobs finished 0847 // 0848 if (!hasSubjobs()) { 0849 Q_EMIT finished(networkItem, process); 0850 } 0851 0852 // 0853 // Clear the network item pointer 0854 // 0855 networkItem.clear(); 0856 0857 // 0858 // Restore the cursor 0859 // 0860 if (!hasSubjobs()) { 0861 QApplication::restoreOverrideCursor(); 0862 } 0863 } 0864 0865 void Smb4KClient::slotAboutToQuit() 0866 { 0867 abort(); 0868 } 0869 0870 void Smb4KClient::slotAbort() 0871 { 0872 abort(); 0873 } 0874 0875 void Smb4KClient::slotCredentialsUpdated(const QUrl &url) 0876 { 0877 if (!url.isEmpty() && !d->queue.isEmpty()) { 0878 QMutableListIterator<Smb4KClientPrivate::QueueContainer> it(d->queue); 0879 0880 while (it.hasNext()) { 0881 Smb4KClientPrivate::QueueContainer container = it.next(); 0882 0883 QUrl networkItemUrl = container.networkItem->url(); 0884 QUrl parentNetworkItemUrl = container.networkItem->url().resolved(QUrl(QStringLiteral(".."))).adjusted(QUrl::StripTrailingSlash); 0885 0886 if (QString::compare(networkItemUrl.toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 0887 url.toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 0888 Qt::CaseInsensitive) 0889 == 0 0890 || QString::compare(parentNetworkItemUrl.toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 0891 url.toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 0892 Qt::CaseInsensitive) 0893 == 0) { 0894 switch (container.networkItem->type()) { 0895 case Host: { 0896 HostPtr host = container.networkItem.staticCast<Smb4KHost>(); 0897 host->setUserName(url.userName()); 0898 host->setPassword(url.password()); 0899 lookupShares(host); 0900 break; 0901 } 0902 case Share: { 0903 SharePtr share = container.networkItem.staticCast<Smb4KShare>(); 0904 share->setUserName(url.userName()); 0905 share->setPassword(url.password()); 0906 if (container.process == Smb4KGlobal::PrintFile) { 0907 printFile(share, container.printFileItem, container.printCopies); 0908 } else { 0909 lookupFiles(share); 0910 } 0911 break; 0912 } 0913 case FileOrDirectory: { 0914 FilePtr file = container.networkItem.staticCast<Smb4KFile>(); 0915 file->setUserName(url.userName()); 0916 file->setPassword(url.password()); 0917 lookupFiles(file); 0918 break; 0919 } 0920 default: { 0921 break; 0922 } 0923 } 0924 0925 it.remove(); 0926 } 0927 } 0928 } 0929 }