File indexing completed on 2024-04-28 12:45:29

0001 /*
0002     Smb4K's container class for information about a share.
0003 
0004     SPDX-FileCopyrightText: 2008-2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 // application specific includes
0009 #include "smb4kshare.h"
0010 #include "smb4kauthinfo.h"
0011 
0012 // Qt include
0013 #include <QDir>
0014 #include <QUrl>
0015 
0016 // KDE includes
0017 #include "kiconthemes_version.h"
0018 #include <KIO/Global>
0019 #include <KIconLoader>
0020 #include <KLocalizedString>
0021 #include <KMountPoint>
0022 
0023 class Smb4KSharePrivate
0024 {
0025 public:
0026     QString workgroup;
0027     QHostAddress ip;
0028     QString path;
0029     bool inaccessible;
0030     bool foreign;
0031     KUser user;
0032     KUserGroup group;
0033     qint64 totalSpace;
0034     qint64 freeSpace;
0035     bool mounted;
0036     QString filesystem;
0037     Smb4KGlobal::ShareType shareType;
0038 };
0039 
0040 Smb4KShare::Smb4KShare(const QUrl &url)
0041     : Smb4KBasicNetworkItem(Share)
0042     , d(new Smb4KSharePrivate)
0043 {
0044     //
0045     // Set the private variables
0046     //
0047     d->inaccessible = false;
0048     d->foreign = false;
0049     d->filesystem = QString();
0050     d->user = KUser(KUser::UseRealUserID);
0051     d->group = KUserGroup(KUser::UseRealUserID);
0052     d->totalSpace = -1;
0053     d->freeSpace = -1;
0054     d->mounted = false;
0055     d->shareType = FileShare;
0056 
0057     //
0058     // Set the URL
0059     //
0060     *pUrl = url;
0061 
0062     //
0063     // Set the icon
0064     //
0065     setShareIcon();
0066 }
0067 
0068 Smb4KShare::Smb4KShare(const Smb4KShare &share)
0069     : Smb4KBasicNetworkItem(share)
0070     , d(new Smb4KSharePrivate)
0071 {
0072     //
0073     // Copy the private variables
0074     //
0075     *d = *share.d;
0076 
0077     //
0078     // Set the icon if necessary
0079     //
0080     if (pIcon->isNull()) {
0081         setShareIcon();
0082     }
0083 }
0084 
0085 Smb4KShare::Smb4KShare()
0086     : Smb4KBasicNetworkItem(Share)
0087     , d(new Smb4KSharePrivate)
0088 {
0089     //
0090     // Set the private variables
0091     //
0092     d->inaccessible = false;
0093     d->foreign = false;
0094     d->filesystem = QString();
0095     d->user = KUser(KUser::UseRealUserID);
0096     d->group = KUserGroup(KUser::UseRealUserID);
0097     d->totalSpace = -1;
0098     d->freeSpace = -1;
0099     d->mounted = false;
0100     d->shareType = FileShare;
0101 
0102     //
0103     // Set the URL
0104     //
0105     pUrl->setScheme(QStringLiteral("smb"));
0106 
0107     //
0108     // Set the icon
0109     //
0110     setShareIcon();
0111 }
0112 
0113 Smb4KShare::~Smb4KShare()
0114 {
0115 }
0116 
0117 void Smb4KShare::setShareName(const QString &name)
0118 {
0119     if (name.startsWith(QStringLiteral("/"))) {
0120         pUrl->setPath(name.trimmed());
0121     } else {
0122         pUrl->setPath(QStringLiteral("/") + name.trimmed());
0123     }
0124 
0125     pUrl->setScheme(QStringLiteral("smb"));
0126 }
0127 
0128 QString Smb4KShare::shareName() const
0129 {
0130     return pUrl->path().remove(QStringLiteral("/"));
0131 }
0132 
0133 void Smb4KShare::setHostName(const QString &hostName)
0134 {
0135     pUrl->setHost(hostName.trimmed());
0136     pUrl->setScheme(QStringLiteral("smb"));
0137 }
0138 
0139 QString Smb4KShare::hostName() const
0140 {
0141     return pUrl->host().toUpper();
0142 }
0143 
0144 QUrl Smb4KShare::homeUrl() const
0145 {
0146     QUrl u;
0147 
0148     if (isHomesShare() && !pUrl->userName().isEmpty()) {
0149         u = *pUrl;
0150         u.setPath(QStringLiteral("/") + pUrl->userName(), QUrl::TolerantMode);
0151     }
0152 
0153     return u;
0154 }
0155 
0156 QString Smb4KShare::displayString(bool showHomesShare) const
0157 {
0158     if (showHomesShare && isHomesShare()) {
0159         return i18n("%1 on %2", homeUrl().path().remove(QStringLiteral("/")), hostName());
0160     }
0161 
0162     return i18n("%1 on %2", shareName(), hostName());
0163 }
0164 
0165 void Smb4KShare::setWorkgroupName(const QString &workgroup)
0166 {
0167     d->workgroup = workgroup;
0168 }
0169 
0170 QString Smb4KShare::workgroupName() const
0171 {
0172     return d->workgroup;
0173 }
0174 
0175 void Smb4KShare::setShareType(Smb4KGlobal::ShareType type)
0176 {
0177     d->shareType = type;
0178     setShareIcon();
0179 }
0180 
0181 Smb4KGlobal::ShareType Smb4KShare::shareType() const
0182 {
0183     return d->shareType;
0184 }
0185 
0186 QString Smb4KShare::shareTypeString() const
0187 {
0188     QString typeString;
0189 
0190     switch (d->shareType) {
0191     case FileShare: {
0192         typeString = i18n("Disk");
0193         break;
0194     }
0195     case PrinterShare: {
0196         typeString = i18n("Printer");
0197         break;
0198     }
0199     case IpcShare: {
0200         typeString = i18n("IPC");
0201         break;
0202     }
0203     default: {
0204         break;
0205     }
0206     }
0207 
0208     return typeString;
0209 }
0210 
0211 void Smb4KShare::setHostIpAddress(const QString &ip)
0212 {
0213     d->ip.setAddress(ip);
0214 }
0215 
0216 void Smb4KShare::setHostIpAddress(const QHostAddress &address)
0217 {
0218     if (!address.isNull() && address.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol) {
0219         d->ip = address;
0220     }
0221 }
0222 
0223 QString Smb4KShare::hostIpAddress() const
0224 {
0225     return d->ip.toString();
0226 }
0227 
0228 bool Smb4KShare::hasHostIpAddress() const
0229 {
0230     return !d->ip.isNull();
0231 }
0232 
0233 bool Smb4KShare::isHidden() const
0234 {
0235     return pUrl->path().endsWith(QStringLiteral("$"));
0236 }
0237 
0238 bool Smb4KShare::isPrinter() const
0239 {
0240     return (d->shareType == PrinterShare);
0241 }
0242 
0243 void Smb4KShare::setPath(const QString &mountpoint)
0244 {
0245     d->path = mountpoint;
0246 }
0247 
0248 QString Smb4KShare::path() const
0249 {
0250     return d->path;
0251 }
0252 
0253 QString Smb4KShare::canonicalPath() const
0254 {
0255     return (d->inaccessible ? d->path : QDir(d->path).canonicalPath());
0256 }
0257 
0258 void Smb4KShare::setInaccessible(bool in)
0259 {
0260     d->inaccessible = in;
0261     setShareIcon();
0262 }
0263 
0264 bool Smb4KShare::isInaccessible() const
0265 {
0266     return (d->mounted && d->inaccessible);
0267 }
0268 
0269 void Smb4KShare::setForeign(bool foreign)
0270 {
0271     d->foreign = foreign;
0272     setShareIcon();
0273 }
0274 
0275 bool Smb4KShare::isForeign() const
0276 {
0277     return (d->mounted && d->foreign);
0278 }
0279 
0280 QString Smb4KShare::fileSystemString() const
0281 {
0282     if (!path().isEmpty() && d->filesystem.isEmpty()) {
0283         KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(path());
0284 
0285         if (mp) {
0286             d->filesystem = mp->mountType().toUpper();
0287         }
0288     }
0289 
0290     return d->filesystem;
0291 }
0292 
0293 void Smb4KShare::setUser(const KUser &user)
0294 {
0295     d->user = user;
0296 }
0297 
0298 KUser Smb4KShare::user() const
0299 {
0300     return d->user;
0301 }
0302 
0303 void Smb4KShare::setGroup(const KUserGroup &group)
0304 {
0305     d->group = group;
0306 }
0307 
0308 KUserGroup Smb4KShare::group() const
0309 {
0310     return d->group;
0311 }
0312 
0313 void Smb4KShare::setMounted(bool mounted)
0314 {
0315     if (!isPrinter()) {
0316         d->mounted = mounted;
0317         setShareIcon();
0318     }
0319 }
0320 
0321 bool Smb4KShare::isMounted() const
0322 {
0323     return d->mounted;
0324 }
0325 
0326 void Smb4KShare::setTotalDiskSpace(qint64 size)
0327 {
0328     d->totalSpace = size;
0329 }
0330 
0331 qint64 Smb4KShare::totalDiskSpace() const
0332 {
0333     return d->totalSpace;
0334 }
0335 
0336 QString Smb4KShare::totalDiskSpaceString() const
0337 {
0338     return KIO::convertSize(static_cast<quint64>(d->totalSpace));
0339 }
0340 
0341 void Smb4KShare::setFreeDiskSpace(qint64 size)
0342 {
0343     d->freeSpace = size;
0344 }
0345 
0346 qint64 Smb4KShare::freeDiskSpace() const
0347 {
0348     return d->freeSpace;
0349 }
0350 
0351 QString Smb4KShare::freeDiskSpaceString() const
0352 {
0353     return KIO::convertSize(static_cast<quint64>(d->freeSpace));
0354 }
0355 
0356 qint64 Smb4KShare::usedDiskSpace() const
0357 {
0358     return (d->totalSpace - d->freeSpace);
0359 }
0360 
0361 QString Smb4KShare::usedDiskSpaceString() const
0362 {
0363     return KIO::convertSize(static_cast<quint64>(usedDiskSpace()));
0364 }
0365 
0366 qreal Smb4KShare::diskUsage() const
0367 {
0368     qreal usage = 0;
0369 
0370     if (d->totalSpace > 0) {
0371         qint64 used = d->totalSpace - d->freeSpace;
0372         usage = static_cast<qreal>(used) * 100 / static_cast<qreal>(d->totalSpace);
0373     }
0374 
0375     return usage;
0376 }
0377 
0378 QString Smb4KShare::diskUsageString() const
0379 {
0380     return QString::number(diskUsage(), 'f', 1) + QStringLiteral(" %");
0381 }
0382 
0383 void Smb4KShare::setMountData(Smb4KShare *share)
0384 {
0385     Q_ASSERT(share);
0386 
0387     if (QString::compare(url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0388                          share->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0389                          Qt::CaseInsensitive)
0390             == 0
0391         && (share->workgroupName().isEmpty() || QString::compare(workgroupName(), share->workgroupName(), Qt::CaseInsensitive) == 0)) {
0392         d->path = share->path();
0393         d->inaccessible = share->isInaccessible();
0394         d->foreign = share->isForeign();
0395         d->user = share->user();
0396         d->group = share->group();
0397         d->totalSpace = share->totalDiskSpace();
0398         d->freeSpace = share->freeDiskSpace();
0399         d->mounted = share->isMounted();
0400         d->shareType = share->shareType();
0401         setShareIcon();
0402     }
0403 }
0404 
0405 void Smb4KShare::resetMountData()
0406 {
0407     d->path.clear();
0408     d->inaccessible = false;
0409     d->foreign = false;
0410     d->user = KUser(KUser::UseRealUserID);
0411     d->group = KUserGroup(KUser::UseRealUserID);
0412     d->totalSpace = -1;
0413     d->freeSpace = -1;
0414     d->mounted = false;
0415     d->shareType = FileShare;
0416     setShareIcon();
0417 }
0418 
0419 bool Smb4KShare::isHomesShare() const
0420 {
0421     return pUrl->path().endsWith(QStringLiteral("homes"));
0422 }
0423 
0424 void Smb4KShare::setPort(int port)
0425 {
0426     pUrl->setPort(port);
0427 }
0428 
0429 int Smb4KShare::port() const
0430 {
0431     return pUrl->port();
0432 }
0433 
0434 void Smb4KShare::setUserName(const QString &name)
0435 {
0436     // Avoid that the login is overwritten with an empty
0437     // string if we have a homes share.
0438     if (!isHomesShare() || !name.isEmpty()) {
0439         pUrl->setUserName(name);
0440     }
0441 }
0442 
0443 QString Smb4KShare::userName() const
0444 {
0445     return pUrl->userName();
0446 }
0447 
0448 void Smb4KShare::setPassword(const QString &passwd)
0449 {
0450     // Avoid that the password is overwritten with an empty
0451     // string if we have a homes share.
0452     if (!isHomesShare() || !passwd.isEmpty()) {
0453         pUrl->setPassword(passwd);
0454     }
0455 }
0456 
0457 QString Smb4KShare::password() const
0458 {
0459     return pUrl->password();
0460 }
0461 
0462 void Smb4KShare::setShareIcon()
0463 {
0464     if (!isPrinter()) {
0465         // Overlays
0466         QStringList overlays;
0467 
0468         if (isInaccessible()) {
0469             overlays << QStringLiteral("emblem-locked");
0470         } else if (isForeign()) {
0471             overlays << QStringLiteral("emblem-warning");
0472         } else if (isMounted()) {
0473             overlays << QStringLiteral("emblem-mounted");
0474         }
0475 
0476         *pIcon = KDE::icon(QStringLiteral("folder-network"), overlays);
0477     } else {
0478         *pIcon = KDE::icon(QStringLiteral("printer"));
0479     }
0480 }
0481 
0482 void Smb4KShare::update(Smb4KShare *share)
0483 {
0484     if (QString::compare(workgroupName(), share->workgroupName(), Qt::CaseInsensitive) == 0
0485         && (QString::compare(url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0486                              share->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0487                              Qt::CaseInsensitive)
0488                 == 0
0489             || QString::compare(homeUrl().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0490                                 share->homeUrl().toString(QUrl::RemoveUserInfo | QUrl::RemovePort),
0491                                 Qt::CaseInsensitive)
0492                 == 0)) {
0493         *pUrl = share->url();
0494         setMountData(share);
0495         setShareType(share->shareType());
0496         setComment(share->comment());
0497         setHostIpAddress(share->hostIpAddress());
0498     }
0499 }
0500 
0501 Smb4KShare &Smb4KShare::operator=(const Smb4KShare &other)
0502 {
0503     *d = *other.d;
0504     return *this;
0505 }