File indexing completed on 2024-04-21 05:47:44
0001 /************************************************************************************* 0002 * Copyright (C) 2012 by Alejandro Fiestas Olivares <afiestas@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "mountinfo.h" 0020 0021 #include <QtCore/QProcess> 0022 #include <QDir> 0023 0024 #include <QDebug> 0025 #include <KColorScheme> 0026 #include <solid/device.h> 0027 #include <solid/storageaccess.h> 0028 #include <KPixmapSequenceOverlayPainter> 0029 #include <KLineEdit> 0030 #include <KDesktopFile> 0031 #include "kpasswdserver_interface.h" 0032 0033 MountInfo::MountInfo(OrgKdeKPasswdServerInterface* iface, KConfigGroup config, QWidget* parent) 0034 : QWidget(parent) 0035 , m_share(false) 0036 , m_mount(false) 0037 , m_editMode(false) 0038 , m_process(new QProcess) 0039 , m_config(config) 0040 , m_painter1(new KPixmapSequenceOverlayPainter) 0041 , m_painter2(new KPixmapSequenceOverlayPainter) 0042 , m_interface(iface) 0043 { 0044 setupUi(this); 0045 0046 m_painter1->setWidget(working1); 0047 m_painter2->setWidget(working2); 0048 0049 KColorScheme scheme(QPalette::Normal); 0050 0051 QPalette palette(error->palette()); 0052 palette.setColor(QPalette::Foreground, scheme.foreground(KColorScheme::NegativeText).color()); 0053 0054 error->setPalette(palette); 0055 0056 sambaRequester->setUrl(QUrl("smb://")); 0057 connect(sambaRequester, SIGNAL(urlSelected(QUrl)), SLOT(checkValidSamba(QUrl))); 0058 connect(sambaRequester, SIGNAL(textChanged(QString)),SLOT(checkValidSamba(QString))); 0059 connect(username, &QLineEdit::textChanged, this, &MountInfo::changed); 0060 connect(password, &QLineEdit::textChanged, this, &MountInfo::changed); 0061 0062 connect(m_process, SIGNAL(finished(int)), SLOT(nameResolveFinished(int))); 0063 0064 connect(shareName, SIGNAL(textChanged(QString)), SLOT(checkMountPoint(QString))); 0065 0066 connect(saveButton, SIGNAL(clicked(bool)), SLOT(buttonClicked())); 0067 0068 connect(m_interface, &OrgKdeKPasswdServerInterface::checkAuthInfoAsyncResult, this, &MountInfo::authInfoReceived); 0069 } 0070 0071 MountInfo::~MountInfo() 0072 { 0073 delete m_process; 0074 delete m_painter1; 0075 delete m_painter2; 0076 } 0077 0078 QString MountInfo::id() const 0079 { 0080 return m_id; 0081 } 0082 0083 void MountInfo::setConfigGroup(const QString& name) 0084 { 0085 m_id = name; 0086 sambaRequester->setUrl(m_config.group(name).readEntry("fullSambaUrl")); 0087 shareName->setText(m_config.group(name).readEntry("mountName")); 0088 username->setText(m_config.group(name).readEntry("username")); 0089 password->setText(m_config.group(name).readEntry("password")); 0090 0091 setEditMode(); 0092 } 0093 0094 void MountInfo::checkValidSamba(const QString& url) 0095 { 0096 checkValidSamba(QUrl(url)); 0097 } 0098 0099 void MountInfo::checkValidSamba(const QUrl &url) 0100 { 0101 KIO::AuthInfo info; 0102 info.url = url; 0103 m_interface->checkAuthInfoAsync(info, window()->winId(), 0); 0104 0105 qDebug() << "check valid url. Host: " << url.host() << url; 0106 m_process->close(); 0107 0108 m_share = false; 0109 setResult(working1, Empty); 0110 0111 m_fullSambaUrl = url.url(); 0112 //If path and file are the same thing for example smb://foo/public 0113 m_sambaDir = url.path(); 0114 0115 qDebug() << "fullSambaUrl" << m_fullSambaUrl << "sambaDir:" << m_sambaDir; 0116 if (m_sambaDir.isEmpty() || m_sambaDir == "/") { 0117 error->setText(i18n("You must select a folder")); 0118 setResult(working1, Fail); 0119 return; 0120 } 0121 0122 m_host = url.host(); 0123 if (isIp(m_host)) 0124 checkValidIp(m_host); 0125 else 0126 checkValidHost(m_host); 0127 0128 Q_EMIT changed(); 0129 } 0130 0131 bool MountInfo::isIp(const QString& host) 0132 { 0133 QStringList split = host.split('.'); 0134 if (split.count() != 4) { 0135 return false; 0136 } 0137 0138 Q_FOREACH(const QString &oc, split) { 0139 if (oc.toInt() > 254) { 0140 return false; 0141 } 0142 } 0143 0144 return true; 0145 } 0146 0147 void MountInfo::checkValidIp(const QString& host) 0148 { 0149 m_painter1->start(); 0150 0151 QStringList args; 0152 args.append("-T"); 0153 args.append("-A"); 0154 args.append(host); 0155 qDebug() << "valid IP" << args; 0156 m_process->start("nmblookup", args); 0157 } 0158 0159 void MountInfo::checkValidHost(const QString& host) 0160 { 0161 m_painter1->start(); 0162 m_process->start("nmblookup", QStringList(host)); 0163 } 0164 0165 void MountInfo::nameResolveFinished(int status) 0166 { 0167 qDebug() << "Status: " << status; 0168 0169 m_painter1->stop(); 0170 0171 QByteArray output = m_process->readAllStandardOutput(); 0172 // qDebug() << "name resolved:" << output; 0173 0174 if (output.isEmpty()) { 0175 error->setText(i18n("Couldn't get the server IP")); 0176 setResult(working1, Fail); 0177 return; 0178 } 0179 0180 QString ipLine; 0181 const QList<QByteArray> lines = output.split('\n'); 0182 Q_FOREACH(const QString &line, lines) { 0183 if (line.contains(m_host)) { 0184 ipLine = line; 0185 break; 0186 } 0187 } 0188 QString ip = ipLine.left(ipLine.indexOf(' ')).trimmed(); 0189 0190 qDebug() << "Ip: " << ip; 0191 if (ip.isEmpty() || ip == "name_query") { 0192 error->setText(i18n("Couldn't get the server IP")); 0193 setResult(working1, Fail); 0194 return; 0195 } 0196 0197 if (!isIp(ip)) { 0198 m_ip = m_host; 0199 m_host = ip.toLower(); 0200 } else { 0201 m_ip = ip; 0202 } 0203 0204 m_share = true; 0205 setResult(working1, Ok); 0206 0207 autoFillMountName(); 0208 } 0209 0210 bool MountInfo::checkMountPoint(const QString& name) 0211 { 0212 m_mountName = name; 0213 return checkMountPoint(QUrl::fromLocalFile(QDir::homePath() + "/Network/" + name)); 0214 } 0215 0216 bool MountInfo::checkMountPoint(const QUrl &url) 0217 { 0218 qDebug() << "ckecking mount point..." << url; 0219 QDir dir(url.toLocalFile()); 0220 0221 const QString networkDir(QDir::homePath() + "/Network"); 0222 dir.mkdir(networkDir); 0223 0224 KDesktopFile cfg(networkDir + QString::fromLatin1("/.directory")); 0225 if (cfg.desktopGroup().readEntry("Icon", "").isEmpty()) { 0226 cfg.desktopGroup().writeEntry("Icon", "folder-remote"); 0227 cfg.sync(); 0228 0229 cfg.reparseConfiguration(); 0230 } 0231 0232 m_mount = false; 0233 m_mountPoint = url.toLocalFile(); 0234 0235 if (dir.exists() && dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).count() != 0) { 0236 error->setText(i18n("Please, choose another name")); 0237 setResult(working2, Fail); 0238 Q_EMIT checkDone(); 0239 return false; 0240 } 0241 0242 QList <Solid::Device> devices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess); 0243 Q_FOREACH(const Solid::Device &device, devices) { 0244 if (device.as<Solid::StorageAccess>()->filePath() == url.toLocalFile()) { 0245 error->setText(i18n("Please, choose another name")); 0246 setResult(working2, Fail); 0247 return false; 0248 } 0249 } 0250 0251 m_mount = true; 0252 setResult(working2, Ok); 0253 0254 return true; 0255 } 0256 0257 void MountInfo::setResult(QLabel* lbl, MountInfo::Status status) 0258 { 0259 switch(status) 0260 { 0261 case Empty: 0262 lbl->setPixmap(QPixmap()); 0263 break; 0264 case Ok: 0265 lbl->setPixmap(QIcon::fromTheme("dialog-ok-apply").pixmap(lbl->sizeHint())); 0266 error->clear(); 0267 Q_EMIT checkDone(); 0268 break; 0269 case Fail: 0270 lbl->setPixmap(QIcon::fromTheme("dialog-close").pixmap(lbl->sizeHint())); 0271 Q_EMIT checkDone(); 0272 break; 0273 } 0274 } 0275 0276 void MountInfo::buttonClicked() 0277 { 0278 checkMountPoint(shareName->text()); 0279 checkValidSamba(sambaRequester->url()); 0280 0281 connect(this, SIGNAL(checkDone()), SLOT(mountIsValid())); 0282 } 0283 0284 void MountInfo::mountIsValid() 0285 { 0286 qDebug() << "Mount is valid"; 0287 disconnect(this, SIGNAL(checkDone()), this, SLOT(mountIsValid())); 0288 0289 if (!m_mount || !m_share) { 0290 return; 0291 } 0292 0293 if (m_editMode) { 0294 m_config.deleteGroup(m_id); 0295 } 0296 0297 m_id = m_fullSambaUrl + "-" + m_mountPoint; 0298 0299 KConfigGroup group = m_config.group(m_id); 0300 0301 saveConfig(group); 0302 0303 qDebug() << "Edit mode:" << m_editMode; 0304 if (m_editMode) { 0305 Q_EMIT mountEditted(group); 0306 return; 0307 } 0308 0309 Q_EMIT mountCreated(group); 0310 setEditMode(); 0311 } 0312 0313 void MountInfo::saveConfig() 0314 { 0315 if (m_id.isEmpty() && !m_fullSambaUrl.isEmpty() && !m_mountPoint.isEmpty()) { 0316 m_id = m_fullSambaUrl + "-" + m_mountPoint; 0317 } 0318 0319 if (m_id.isEmpty()) { 0320 return; 0321 } 0322 0323 saveConfig(m_config.group(m_id)); 0324 } 0325 0326 void MountInfo::saveConfig(KConfigGroup group) 0327 { 0328 qDebug() << "Saving mount"; 0329 0330 group.writeEntry("ip", m_ip); 0331 group.writeEntry("hostname", m_host); 0332 group.writeEntry("mountPoint", m_mountPoint); 0333 group.writeEntry("sambaDir", m_sambaDir); 0334 group.writeEntry("fullSambaUrl", m_fullSambaUrl); 0335 group.writeEntry("mountName", m_mountName); 0336 group.writeEntry("username", username->text()); 0337 group.writeEntry("password", password->text()); 0338 0339 group.sync(); 0340 0341 QDir().mkdir(m_mountPoint); 0342 } 0343 0344 void MountInfo::setEditMode() 0345 { 0346 setResult(working1, Empty); 0347 setResult(working2, Empty); 0348 0349 m_editMode = true; 0350 } 0351 0352 void MountInfo::autoFillMountName() 0353 { 0354 if (!shareName->text().isEmpty()) { 0355 return; 0356 } 0357 0358 QString name = sambaRequester->url().fileName(); 0359 0360 if (!checkMountPoint(name)) { 0361 setResult(working2, Empty); 0362 error->clear(); 0363 return; 0364 } 0365 0366 shareName->setText(name); 0367 } 0368 0369 void MountInfo::authInfoReceived(qlonglong /*requestId*/, qlonglong /*seqNr*/, const KIO::AuthInfo & info) 0370 { 0371 if (!username->text().isEmpty() || !password->text().isEmpty()) 0372 return; 0373 0374 if (info.url == sambaRequester->url()) { 0375 // qDebug() << "awesomeeeeeeeeeee" << requestId << info.username << info.password; 0376 username->setText(info.username); 0377 password->setText(info.password); 0378 } 0379 }