File indexing completed on 2024-04-14 15:05:26
0001 /*************************************************************************** 0002 Manage custom options 0003 ------------------- 0004 begin : Fr 29 Apr 2011 0005 copyright : (C) 2011-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 #ifdef HAVE_CONFIG_H 0027 #include <config.h> 0028 #endif 0029 0030 // application specific includes 0031 #include "smb4kcustomoptionsmanager.h" 0032 #include "smb4kcustomoptionsmanager_p.h" 0033 #include "smb4kcustomoptions.h" 0034 #include "smb4khomesshareshandler.h" 0035 #include "smb4knotification.h" 0036 #include "smb4khost.h" 0037 #include "smb4kshare.h" 0038 #include "smb4ksettings.h" 0039 #include "smb4kglobal.h" 0040 #include "smb4kprofilemanager.h" 0041 0042 #if defined(Q_OS_LINUX) 0043 #include "smb4kmountsettings_linux.h" 0044 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) 0045 #include "smb4kmountsettings_bsd.h" 0046 #endif 0047 0048 // Qt includes 0049 #include <QXmlStreamReader> 0050 #include <QXmlStreamWriter> 0051 #include <QDebug> 0052 #include <QApplication> 0053 #include <QPointer> 0054 0055 // KDE includes 0056 #define TRANSLATION_DOMAIN "smb4k-core" 0057 #include <KI18n/KLocalizedString> 0058 0059 using namespace Smb4KGlobal; 0060 0061 Q_GLOBAL_STATIC(Smb4KCustomOptionsManagerStatic, p); 0062 0063 0064 Smb4KCustomOptionsManager::Smb4KCustomOptionsManager(QObject *parent) 0065 : QObject(parent), d(new Smb4KCustomOptionsManagerPrivate) 0066 { 0067 // First we need the directory. 0068 QString path = dataLocation(); 0069 0070 QDir dir; 0071 0072 if (!dir.exists(path)) 0073 { 0074 dir.mkpath(path); 0075 } 0076 0077 readCustomOptions(); 0078 0079 // Connections 0080 connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(slotAboutToQuit())); 0081 } 0082 0083 0084 Smb4KCustomOptionsManager::~Smb4KCustomOptionsManager() 0085 { 0086 } 0087 0088 0089 Smb4KCustomOptionsManager *Smb4KCustomOptionsManager::self() 0090 { 0091 return &p->instance; 0092 } 0093 0094 0095 void Smb4KCustomOptionsManager::addRemount(const SharePtr &share, bool always) 0096 { 0097 if (share) 0098 { 0099 // 0100 // Find the right custom options, if they exist 0101 // 0102 OptionsPtr options = findOptions(share, true); 0103 0104 if (options) 0105 { 0106 // If the options are already in the list, check if the share is 0107 // always to be remounted. If so, ignore the 'always' argument 0108 // and leave that option untouched. 0109 if (options->remount() != Smb4KCustomOptions::RemountAlways) 0110 { 0111 options->setRemount(always ? Smb4KCustomOptions::RemountAlways : Smb4KCustomOptions::RemountOnce); 0112 } 0113 } 0114 else 0115 { 0116 options = OptionsPtr(new Smb4KCustomOptions(share.data())); 0117 options->setProfile(Smb4KProfileManager::self()->activeProfile()); 0118 options->setRemount(always ? Smb4KCustomOptions::RemountAlways : Smb4KCustomOptions::RemountOnce); 0119 d->options << options; 0120 } 0121 0122 // 0123 // Write the custom options 0124 // 0125 writeCustomOptions(); 0126 } 0127 } 0128 0129 0130 void Smb4KCustomOptionsManager::removeRemount(const SharePtr &share, bool force) 0131 { 0132 if (share) 0133 { 0134 // 0135 // Get the remount 0136 // 0137 OptionsPtr options = findOptions(share, true); 0138 0139 // 0140 // Remove the remount flag and, if there are no more options defined, 0141 // the options object itself. Save the modified list to the file afterwards. 0142 // 0143 if (options) 0144 { 0145 if (options->remount() == Smb4KCustomOptions::RemountOnce) 0146 { 0147 options->setRemount(Smb4KCustomOptions::UndefinedRemount); 0148 } 0149 else if (options->remount() == Smb4KCustomOptions::RemountAlways && force) 0150 { 0151 options->setRemount(Smb4KCustomOptions::UndefinedRemount); 0152 } 0153 0154 if (!options->hasOptions()) 0155 { 0156 removeCustomOptions(options, false); 0157 } 0158 } 0159 0160 // 0161 // Write the options 0162 // 0163 writeCustomOptions(); 0164 } 0165 } 0166 0167 0168 void Smb4KCustomOptionsManager::clearRemounts(bool force) 0169 { 0170 // 0171 // Remove the remount flag and, if there are nomore options defined, 0172 // also the options object. Write everything to the file afterwards. 0173 // 0174 for (const OptionsPtr &o : d->options) 0175 { 0176 if (o->type() == Share) 0177 { 0178 if (o->remount() == Smb4KCustomOptions::RemountOnce) 0179 { 0180 o->setRemount(Smb4KCustomOptions::UndefinedRemount); 0181 } 0182 else if (o->remount() == Smb4KCustomOptions::RemountAlways && force) 0183 { 0184 o->setRemount(Smb4KCustomOptions::UndefinedRemount); 0185 } 0186 } 0187 0188 if (!o->hasOptions()) 0189 { 0190 removeCustomOptions(o, false); 0191 } 0192 } 0193 0194 // 0195 // Write the options 0196 // 0197 writeCustomOptions(); 0198 } 0199 0200 0201 QList<OptionsPtr> Smb4KCustomOptionsManager::sharesToRemount() 0202 { 0203 // 0204 // List of relevant custom options 0205 // 0206 QList<OptionsPtr> options = customOptions(false); 0207 0208 // 0209 // List of remounts 0210 // 0211 QList<OptionsPtr> remounts; 0212 0213 // 0214 // Get the list of remounts 0215 // 0216 for (const OptionsPtr &o : options) 0217 { 0218 if (o->remount() == Smb4KCustomOptions::RemountOnce) 0219 { 0220 remounts << o; 0221 } 0222 else if (o->remount() == Smb4KCustomOptions::RemountAlways) 0223 { 0224 remounts << o; 0225 } 0226 } 0227 0228 // 0229 // Return relevant options 0230 // 0231 return remounts; 0232 } 0233 0234 0235 OptionsPtr Smb4KCustomOptionsManager::findOptions(const NetworkItemPtr &networkItem, bool exactMatch) 0236 { 0237 // 0238 // The options that are to be returned 0239 // 0240 OptionsPtr options; 0241 0242 // 0243 // Get the list of options 0244 // 0245 QList<OptionsPtr> optionsList = customOptions(false); 0246 0247 // 0248 // Only do something if the list of options is not empty. 0249 // 0250 if (!optionsList.isEmpty()) 0251 { 0252 for (const OptionsPtr &opt : optionsList) 0253 { 0254 // 0255 // If we want to have an exact match, skip all options that do not match 0256 // 0257 if (exactMatch) 0258 { 0259 if (networkItem->type() != opt->type() || 0260 QString::compare(networkItem->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), 0261 opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) != 0) 0262 { 0263 continue; 0264 } 0265 } 0266 0267 // 0268 // Now assign the options 0269 // 0270 if (networkItem->type() == Host && opt->type() == Host) 0271 { 0272 HostPtr host = networkItem.staticCast<Smb4KHost>(); 0273 0274 if (host) 0275 { 0276 if (QString::compare(host->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), 0277 opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0 || 0278 (host->url().isEmpty() && host->ipAddress() == opt->ipAddress())) 0279 { 0280 options = opt; 0281 break; 0282 } 0283 } 0284 } 0285 else if (networkItem->type() == Share) 0286 { 0287 SharePtr share = networkItem.staticCast<Smb4KShare>(); 0288 0289 if (share) 0290 { 0291 if (opt->type() == Share && 0292 QString::compare(share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), 0293 opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0) 0294 { 0295 // Since this is the exact match, break here 0296 options = opt; 0297 break; 0298 } 0299 else if (opt->type() == Host && 0300 QString::compare(share->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath|QUrl::StripTrailingSlash), 0301 opt->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::RemovePath|QUrl::StripTrailingSlash), Qt::CaseInsensitive) == 0) 0302 { 0303 // These options belong to the host. Do not break here, 0304 // because there might still be an exact match 0305 options = opt; 0306 } 0307 } 0308 } 0309 } 0310 } 0311 0312 // 0313 // Return the options 0314 // 0315 return options; 0316 } 0317 0318 0319 OptionsPtr Smb4KCustomOptionsManager::findOptions(const QUrl &url) 0320 { 0321 // 0322 // The options that are to be returned 0323 // 0324 OptionsPtr options; 0325 0326 // 0327 // Search the options for the given URL 0328 // 0329 if (url.isValid() && url.scheme() == "smb") 0330 { 0331 // 0332 // Get the relevant options 0333 // 0334 QList<OptionsPtr> optionsList = customOptions(false); 0335 0336 // 0337 // Get the options 0338 // 0339 for (const OptionsPtr &o : optionsList) 0340 { 0341 if (o->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash) == 0342 url.toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash)) 0343 { 0344 options = o; 0345 break; 0346 } 0347 } 0348 } 0349 0350 // 0351 // Return the options 0352 // 0353 return options; 0354 } 0355 0356 0357 void Smb4KCustomOptionsManager::readCustomOptions() 0358 { 0359 // 0360 // Clear the list of options 0361 // 0362 while (!d->options.isEmpty()) 0363 { 0364 d->options.takeFirst().clear(); 0365 } 0366 0367 // 0368 // Set the XML file 0369 // 0370 QFile xmlFile(dataLocation()+QDir::separator()+"custom_options.xml"); 0371 0372 if (xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) 0373 { 0374 QXmlStreamReader xmlReader(&xmlFile); 0375 0376 while (!xmlReader.atEnd()) 0377 { 0378 xmlReader.readNext(); 0379 0380 if (xmlReader.isStartElement()) 0381 { 0382 if (xmlReader.name() == "custom_options" && 0383 (xmlReader.attributes().value("version") != "1.2" && xmlReader.attributes().value("version") != "2.0")) 0384 { 0385 xmlReader.raiseError(i18n("The format of %1 is not supported.", xmlFile.fileName())); 0386 break; 0387 } 0388 else 0389 { 0390 if (xmlReader.name() == "options") 0391 { 0392 OptionsPtr options = OptionsPtr(new Smb4KCustomOptions()); 0393 options->setProfile(xmlReader.attributes().value("profile").toString()); 0394 0395 // 0396 // Initialize the options 0397 // 0398 if (QString::compare(xmlReader.attributes().value("type").toString(), "host", Qt::CaseInsensitive) == 0) 0399 { 0400 options->setHost(new Smb4KHost()); 0401 } 0402 else 0403 { 0404 options->setShare(new Smb4KShare()); 0405 } 0406 0407 while (!(xmlReader.isEndElement() && xmlReader.name() == "options")) 0408 { 0409 xmlReader.readNext(); 0410 0411 if (xmlReader.isStartElement()) 0412 { 0413 if (xmlReader.name() == "workgroup") 0414 { 0415 options->setWorkgroupName(xmlReader.readElementText()); 0416 } 0417 else if (xmlReader.name() == "url") 0418 { 0419 QUrl url(xmlReader.readElementText()); 0420 options->setUrl(url); 0421 } 0422 else if (xmlReader.name() == "unc") 0423 { 0424 QUrl url = QUrl::fromUserInput(xmlReader.readElementText()); 0425 url.setScheme("smb"); 0426 options->setUrl(url); 0427 } 0428 else if (xmlReader.name() == "ip") 0429 { 0430 options->setIpAddress(xmlReader.readElementText()); 0431 } 0432 else if (xmlReader.name() == "custom") 0433 { 0434 while (!(xmlReader.isEndElement() && xmlReader.name() == "custom")) 0435 { 0436 xmlReader.readNext(); 0437 0438 if (xmlReader.isStartElement()) 0439 { 0440 if (xmlReader.name() == "smb_port") 0441 { 0442 bool ok = false; 0443 0444 int portNumber = xmlReader.readElementText().toInt(&ok); 0445 0446 if (ok) 0447 { 0448 options->setSmbPort(portNumber); 0449 } 0450 } 0451 else if (xmlReader.name() == "use_smb_port") 0452 { 0453 QString useSmbPort = xmlReader.readElementText(); 0454 0455 if (useSmbPort == "true") 0456 { 0457 options->setUseSmbPort(true); 0458 } 0459 else 0460 { 0461 options->setUseSmbPort(false); 0462 } 0463 } 0464 else if (xmlReader.name() == "kerberos") 0465 { 0466 QString useKerberos = xmlReader.readElementText(); 0467 0468 if (useKerberos == "true") 0469 { 0470 options->setUseKerberos(true); 0471 } 0472 else 0473 { 0474 options->setUseKerberos(false); 0475 } 0476 } 0477 else if (xmlReader.name() == "mac_address") 0478 { 0479 QString macAddress = xmlReader.readElementText(); 0480 0481 QRegExp exp("..\\:..\\:..\\:..\\:..\\:.."); 0482 0483 if (exp.exactMatch(macAddress)) 0484 { 0485 options->setMACAddress(macAddress); 0486 } 0487 } 0488 else if (xmlReader.name() == "wol_send_before_first_scan") 0489 { 0490 QString send = xmlReader.readElementText(); 0491 0492 if (send == "true") 0493 { 0494 options->setWOLSendBeforeNetworkScan(true); 0495 } 0496 else 0497 { 0498 options->setWOLSendBeforeNetworkScan(false); 0499 } 0500 } 0501 else if (xmlReader.name() == "wol_send_before_mount") 0502 { 0503 QString send = xmlReader.readElementText(); 0504 0505 if (send == "true") 0506 { 0507 options->setWOLSendBeforeMount(true); 0508 } 0509 else 0510 { 0511 options->setWOLSendBeforeMount(false); 0512 } 0513 } 0514 else if (xmlReader.name() == "remount") 0515 { 0516 QString remount = xmlReader.readElementText(); 0517 0518 if (remount == "once") 0519 { 0520 options->setRemount(Smb4KCustomOptions::RemountOnce); 0521 } 0522 else if (remount == "always") 0523 { 0524 options->setRemount(Smb4KCustomOptions::RemountAlways); 0525 } 0526 else 0527 { 0528 options->setRemount(Smb4KCustomOptions::UndefinedRemount); 0529 } 0530 } 0531 else if (xmlReader.name() == "use_user") 0532 { 0533 QString useUser = xmlReader.readElementText(); 0534 0535 if (useUser == "true") 0536 { 0537 options->setUseUser(true); 0538 } 0539 else 0540 { 0541 options->setUseUser(false); 0542 } 0543 } 0544 else if (xmlReader.name() == "uid") 0545 { 0546 KUser user((K_UID)xmlReader.readElementText().toInt()); 0547 0548 if (user.isValid()) 0549 { 0550 options->setUser(user); 0551 } 0552 } 0553 else if (xmlReader.name() == "use_group") 0554 { 0555 QString useGroup = xmlReader.readElementText(); 0556 0557 if (useGroup == "true") 0558 { 0559 options->setUseGroup(true); 0560 } 0561 else 0562 { 0563 options->setUseGroup(false); 0564 } 0565 } 0566 else if (xmlReader.name() == "gid") 0567 { 0568 KUserGroup group((K_GID)xmlReader.readElementText().toInt()); 0569 0570 if (group.isValid()) 0571 { 0572 options->setGroup(group); 0573 } 0574 } 0575 else if (xmlReader.name() == "use_file_mode") 0576 { 0577 QString useFileMode = xmlReader.readElementText(); 0578 0579 if (useFileMode == "true") 0580 { 0581 options->setUseFileMode(true); 0582 } 0583 else 0584 { 0585 options->setUseFileMode(false); 0586 } 0587 } 0588 else if (xmlReader.name() == "file_mode") 0589 { 0590 options->setFileMode(xmlReader.readElementText()); 0591 } 0592 else if (xmlReader.name() == "use_directory_mode") 0593 { 0594 QString useDirectoryMode = xmlReader.readElementText(); 0595 0596 if (useDirectoryMode == "true") 0597 { 0598 options->setUseDirectoryMode(true); 0599 } 0600 else 0601 { 0602 options->setUseDirectoryMode(false); 0603 } 0604 } 0605 else if (xmlReader.name() == "directory_mode") 0606 { 0607 options->setDirectoryMode(xmlReader.readElementText()); 0608 } 0609 #if defined(Q_OS_LINUX) 0610 else if (xmlReader.name() == "cifs_unix_extensions_support") 0611 { 0612 QString support = xmlReader.readElementText(); 0613 0614 if (support == "true") 0615 { 0616 options->setCifsUnixExtensionsSupport(true); 0617 } 0618 else 0619 { 0620 options->setCifsUnixExtensionsSupport(false); 0621 } 0622 } 0623 else if (xmlReader.name() == "use_filesystem_port") 0624 { 0625 QString useFilesystemPort = xmlReader.readElementText(); 0626 0627 if (useFilesystemPort == "true") 0628 { 0629 options->setUseFileSystemPort(true); 0630 } 0631 else 0632 { 0633 options->setUseFileSystemPort(false); 0634 } 0635 } 0636 else if (xmlReader.name() == "filesystem_port") 0637 { 0638 bool ok = false; 0639 0640 int portNumber = xmlReader.readElementText().toInt(&ok); 0641 0642 if (ok) 0643 { 0644 options->setFileSystemPort(portNumber); 0645 } 0646 } 0647 else if (xmlReader.name() == "use_security_mode") 0648 { 0649 QString useSecurityMode = xmlReader.readElementText(); 0650 0651 if (useSecurityMode == "true") 0652 { 0653 options->setUseSecurityMode(true); 0654 } 0655 else 0656 { 0657 options->setUseSecurityMode(false); 0658 } 0659 } 0660 else if (xmlReader.name() == "security_mode") 0661 { 0662 QString securityMode = xmlReader.readElementText(); 0663 0664 if (securityMode == "none") 0665 { 0666 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::None); 0667 } 0668 else if (securityMode == "krb5") 0669 { 0670 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5); 0671 } 0672 else if (securityMode == "krb5i") 0673 { 0674 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Krb5i); 0675 } 0676 else if (securityMode == "ntlm") 0677 { 0678 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlm); 0679 } 0680 else if (securityMode == "ntlmi") 0681 { 0682 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmi); 0683 } 0684 else if (securityMode == "ntlmv2") 0685 { 0686 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2); 0687 } 0688 else if (securityMode == "ntlmv2i") 0689 { 0690 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmv2i); 0691 } 0692 else if (securityMode == "ntlmssp") 0693 { 0694 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmssp); 0695 } 0696 else if (securityMode == "ntlmsspi") 0697 { 0698 options->setSecurityMode(Smb4KMountSettings::EnumSecurityMode::Ntlmsspi); 0699 } 0700 } 0701 else if (xmlReader.name() == "use_write_access") 0702 { 0703 QString useWriteAccess = xmlReader.readElementText(); 0704 0705 if (useWriteAccess == "true") 0706 { 0707 options->setUseWriteAccess(true); 0708 } 0709 else 0710 { 0711 options->setUseWriteAccess(false); 0712 } 0713 } 0714 else if (xmlReader.name() == "write_access") 0715 { 0716 QString writeAccess = xmlReader.readElementText(); 0717 0718 if (writeAccess == "true") 0719 { 0720 options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadWrite); 0721 } 0722 else if (writeAccess == "false") 0723 { 0724 options->setWriteAccess(Smb4KMountSettings::EnumWriteAccess::ReadWrite); 0725 } 0726 } 0727 #endif 0728 } 0729 } 0730 } 0731 0732 continue; 0733 } 0734 else 0735 { 0736 continue; 0737 } 0738 } 0739 0740 d->options << options; 0741 } 0742 } 0743 } 0744 } 0745 0746 xmlFile.close(); 0747 0748 if (xmlReader.hasError()) 0749 { 0750 Smb4KNotification::readingFileFailed(xmlFile, xmlReader.errorString()); 0751 } 0752 } 0753 else 0754 { 0755 if (xmlFile.exists()) 0756 { 0757 Smb4KNotification::openingFileFailed(xmlFile); 0758 } 0759 } 0760 } 0761 0762 0763 void Smb4KCustomOptionsManager::writeCustomOptions() 0764 { 0765 // 0766 // Set the XML file 0767 // 0768 QFile xmlFile(dataLocation()+QDir::separator()+"custom_options.xml"); 0769 0770 // 0771 // Write the options to the file 0772 // 0773 if (!d->options.isEmpty()) 0774 { 0775 if (xmlFile.open(QIODevice::WriteOnly|QIODevice::Text)) 0776 { 0777 QXmlStreamWriter xmlWriter(&xmlFile); 0778 xmlWriter.setAutoFormatting(true); 0779 xmlWriter.writeStartDocument(); 0780 xmlWriter.writeStartElement("custom_options"); 0781 xmlWriter.writeAttribute("version", "2.0"); 0782 0783 for (const OptionsPtr &options : d->options) 0784 { 0785 if (options->hasOptions() || options->remount() == Smb4KCustomOptions::RemountOnce) 0786 { 0787 xmlWriter.writeStartElement("options"); 0788 xmlWriter.writeAttribute("type", options->type() == Host ? "host" : "share"); 0789 xmlWriter.writeAttribute("profile", options->profile()); 0790 0791 xmlWriter.writeTextElement("workgroup", options->workgroupName()); 0792 xmlWriter.writeTextElement("url", options->url().toDisplayString()); 0793 xmlWriter.writeTextElement("ip", options->ipAddress()); 0794 0795 xmlWriter.writeStartElement("custom"); 0796 0797 QMap<QString,QString> map = options->customOptions(); 0798 QMapIterator<QString,QString> it(map); 0799 0800 while (it.hasNext()) 0801 { 0802 it.next(); 0803 0804 if (!it.value().isEmpty()) 0805 { 0806 xmlWriter.writeTextElement(it.key(), it.value()); 0807 } 0808 } 0809 0810 xmlWriter.writeEndElement(); 0811 xmlWriter.writeEndElement(); 0812 } 0813 } 0814 0815 xmlWriter.writeEndDocument(); 0816 xmlFile.close(); 0817 } 0818 else 0819 { 0820 Smb4KNotification::openingFileFailed(xmlFile); 0821 } 0822 } 0823 else 0824 { 0825 xmlFile.remove(); 0826 } 0827 } 0828 0829 0830 QList<OptionsPtr> Smb4KCustomOptionsManager::customOptions(bool optionsOnly) 0831 { 0832 // 0833 // Options list 0834 // 0835 QList<OptionsPtr> options; 0836 0837 // 0838 // Get this list of options 0839 // 0840 for (const OptionsPtr &o : d->options) 0841 { 0842 if (Smb4KSettings::useProfiles() && o->profile() != Smb4KProfileManager::self()->activeProfile()) 0843 { 0844 continue; 0845 } 0846 0847 if (o->hasOptions() || (!optionsOnly && o->remount() == Smb4KCustomOptions::RemountOnce)) 0848 { 0849 options << o; 0850 } 0851 } 0852 0853 // 0854 // Return the list of relevant options 0855 // 0856 return options; 0857 } 0858 0859 0860 void Smb4KCustomOptionsManager::replaceCustomOptions(const QList<OptionsPtr> &optionsList) 0861 { 0862 // 0863 // Clear the list of options. Honor profiles. 0864 // 0865 QMutableListIterator<OptionsPtr> it(d->options); 0866 0867 while (it.hasNext()) 0868 { 0869 OptionsPtr options = it.next(); 0870 0871 if (Smb4KSettings::useProfiles() && options->profile() != Smb4KProfileManager::self()->activeProfile()) 0872 { 0873 continue; 0874 } 0875 0876 it.remove(); 0877 } 0878 0879 // 0880 // Append the new list 0881 // 0882 if (!optionsList.isEmpty()) 0883 { 0884 for (const OptionsPtr &options : optionsList) 0885 { 0886 if (Smb4KSettings::useProfiles()) 0887 { 0888 options->setProfile(Smb4KProfileManager::self()->activeProfile()); 0889 } 0890 0891 if (options->hasOptions() || options->remount() == Smb4KCustomOptions::RemountOnce) 0892 { 0893 d->options << options; 0894 } 0895 } 0896 } 0897 0898 writeCustomOptions(); 0899 } 0900 0901 0902 void Smb4KCustomOptionsManager::openCustomOptionsDialog(const NetworkItemPtr &item) 0903 { 0904 if (item) 0905 { 0906 OptionsPtr options; 0907 0908 switch (item->type()) 0909 { 0910 case Host: 0911 { 0912 HostPtr host = item.staticCast<Smb4KHost>(); 0913 0914 if (host) 0915 { 0916 options = findOptions(host); 0917 0918 if (!options) 0919 { 0920 options = OptionsPtr(new Smb4KCustomOptions(host.data())); 0921 options->setProfile(Smb4KProfileManager::self()->activeProfile()); 0922 } 0923 } 0924 0925 break; 0926 } 0927 case Share: 0928 { 0929 SharePtr share = item.staticCast<Smb4KShare>(); 0930 0931 if (share && !share->isPrinter()) 0932 { 0933 if (share->isHomesShare()) 0934 { 0935 if (!Smb4KHomesSharesHandler::self()->specifyUser(share, true)) 0936 { 0937 return; 0938 } 0939 } 0940 0941 options = findOptions(share); 0942 0943 if (!options) 0944 { 0945 options = OptionsPtr(new Smb4KCustomOptions(share.data())); 0946 options->setProfile(Smb4KProfileManager::self()->activeProfile()); 0947 0948 // Get rid of the 'homes' share 0949 if (share->isHomesShare()) 0950 { 0951 options->setUrl(share->homeUrl()); 0952 } 0953 } 0954 else 0955 { 0956 // In case the custom options object for the host has been 0957 // returned, change its internal network item, otherwise we 0958 // will change the host's custom options... 0959 options->setShare(share.data()); 0960 } 0961 } 0962 0963 break; 0964 } 0965 default: 0966 { 0967 break; 0968 } 0969 } 0970 0971 if (options) 0972 { 0973 QPointer<Smb4KCustomOptionsDialog> dlg = new Smb4KCustomOptionsDialog(options, QApplication::activeWindow()); 0974 0975 if (dlg->exec() == QDialog::Accepted) 0976 { 0977 if (options->hasOptions()) 0978 { 0979 addCustomOptions(options, true); 0980 } 0981 else 0982 { 0983 removeCustomOptions(options, true); 0984 } 0985 } 0986 else 0987 { 0988 resetCustomOptions(); 0989 } 0990 0991 delete dlg; 0992 } 0993 } 0994 } 0995 0996 0997 void Smb4KCustomOptionsManager::addCustomOptions(const OptionsPtr &options, bool write) 0998 { 0999 if (options) 1000 { 1001 // 1002 // Check if options for the URL already exist 1003 // 1004 OptionsPtr knownOptions = findOptions(options->url()); 1005 1006 if (knownOptions) 1007 { 1008 // 1009 // Update the options 1010 // 1011 knownOptions->update(options.data()); 1012 } 1013 else 1014 { 1015 // 1016 // Add the options 1017 // 1018 if (options->profile().isEmpty()) 1019 { 1020 options->setProfile(Smb4KProfileManager::self()->activeProfile()); 1021 } 1022 1023 d->options << options; 1024 } 1025 1026 // 1027 // In case the options are defined for a host, propagate them 1028 // to the options of shares belonging to that host. Overwrite 1029 // the settings 1030 // 1031 if (options->type() == Host) 1032 { 1033 for (const OptionsPtr &o : d->options) 1034 { 1035 if (o->type() == Share && o->hostName() == options->hostName() && o->workgroupName() == options->workgroupName()) 1036 { 1037 o->setIpAddress(options->ipAddress()); 1038 o->setUseUser(options->useUser()); 1039 o->setUser(options->user()); 1040 o->setUseGroup(options->useGroup()); 1041 o->setGroup(options->group()); 1042 o->setUseFileMode(options->useFileMode()); 1043 o->setFileMode(options->fileMode()); 1044 o->setUseDirectoryMode(options->useDirectoryMode()); 1045 o->setDirectoryMode(options->directoryMode()); 1046 #if defined(Q_OS_LINUX) 1047 o->setCifsUnixExtensionsSupport(options->cifsUnixExtensionsSupport()); 1048 o->setUseFileSystemPort(options->useFileSystemPort()); 1049 o->setFileSystemPort(options->fileSystemPort()); 1050 o->setUseSecurityMode(options->useSecurityMode()); 1051 o->setSecurityMode(options->securityMode()); 1052 o->setUseWriteAccess(options->useWriteAccess()); 1053 o->setWriteAccess(options->writeAccess()); 1054 #endif 1055 o->setUseSmbPort(options->useSmbPort()); 1056 o->setSmbPort(options->smbPort()); 1057 o->setUseKerberos(options->useKerberos()); 1058 o->setMACAddress(options->macAddress()); 1059 o->setWOLSendBeforeNetworkScan(options->wolSendBeforeNetworkScan()); 1060 o->setWOLSendBeforeMount(options->wolSendBeforeMount()); 1061 } 1062 } 1063 } 1064 1065 // 1066 // Write the custom options to the file, if desired 1067 // 1068 if (write) 1069 { 1070 writeCustomOptions(); 1071 } 1072 } 1073 } 1074 1075 1076 void Smb4KCustomOptionsManager::removeCustomOptions(const OptionsPtr &options, bool write) 1077 { 1078 if (options) 1079 { 1080 // 1081 // Find the custom options and remove them 1082 // 1083 for (int i = 0; i < d->options.size(); ++i) 1084 { 1085 if ((!Smb4KSettings::useProfiles() || Smb4KProfileManager::self()->activeProfile() == d->options.at(i)->profile()) && 1086 d->options.at(i)->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash) == 1087 options->url().toString(QUrl::RemoveUserInfo|QUrl::RemovePort|QUrl::StripTrailingSlash)) 1088 { 1089 d->options.takeAt(i).clear(); 1090 break; 1091 } 1092 } 1093 1094 // 1095 // Write the custom options to the file, if desired 1096 // 1097 if (write) 1098 { 1099 writeCustomOptions(); 1100 } 1101 } 1102 } 1103 1104 1105 QList<OptionsPtr> Smb4KCustomOptionsManager::wakeOnLanEntries() const 1106 { 1107 QList<OptionsPtr> list; 1108 1109 // 1110 // Get the Wake-On-LAN entries 1111 // 1112 for (const OptionsPtr &options : d->options) 1113 { 1114 if (!options->macAddress().isEmpty() && (options->wolSendBeforeNetworkScan() || options->wolSendBeforeMount())) 1115 { 1116 list << options; 1117 } 1118 } 1119 1120 // 1121 // Return them 1122 // 1123 return list; 1124 } 1125 1126 1127 void Smb4KCustomOptionsManager::resetCustomOptions() 1128 { 1129 readCustomOptions(); 1130 } 1131 1132 1133 void Smb4KCustomOptionsManager::migrateProfile(const QString& from, const QString& to) 1134 { 1135 // 1136 // Replace the old with the new profile 1137 // 1138 for (const OptionsPtr &options : d->options) 1139 { 1140 if (options->profile() == from) 1141 { 1142 options->setProfile(to); 1143 } 1144 } 1145 1146 // 1147 // Write all custom options to the file. 1148 // 1149 writeCustomOptions(); 1150 } 1151 1152 1153 void Smb4KCustomOptionsManager::removeProfile(const QString& name) 1154 { 1155 // 1156 // Remove all entries belonging to the profile 1157 // 1158 QMutableListIterator<OptionsPtr> it(d->options); 1159 1160 while (it.hasNext()) 1161 { 1162 OptionsPtr options = it.next(); 1163 1164 if (QString::compare(options->profile(), name, Qt::CaseSensitive) == 0) 1165 { 1166 it.remove(); 1167 } 1168 } 1169 1170 // 1171 // Write all custom options to the file. 1172 // 1173 writeCustomOptions(); 1174 } 1175 1176 1177 ///////////////////////////////////////////////////////////////////////////// 1178 // SLOT IMPLEMENTATIONS 1179 ///////////////////////////////////////////////////////////////////////////// 1180 1181 void Smb4KCustomOptionsManager::slotAboutToQuit() 1182 { 1183 writeCustomOptions(); 1184 } 1185 1186