diff --git a/src/core/authinfo.cpp b/src/core/authinfo.cpp index d047dc6f..9ba727fc 100644 --- a/src/core/authinfo.cpp +++ b/src/core/authinfo.cpp @@ -1,481 +1,481 @@ /* * This file is part of the KDE libraries * Copyright (C) 2000-2001 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "authinfo.h" #include #include #include #include #include #include #include #include using namespace KIO; ////// class ExtraField { public: ExtraField() : flags(AuthInfo::ExtraFieldNoFlags) { } ExtraField(const ExtraField &other) : customTitle(other.customTitle), flags(other.flags), value(other.value) { } ExtraField &operator=(const ExtraField &other) { customTitle = other.customTitle; flags = other.flags; value = other.value; return *this; } QString customTitle; // reserved for future use AuthInfo::FieldFlags flags; QVariant value; }; Q_DECLARE_METATYPE(ExtraField) static QDataStream &operator<< (QDataStream &s, const ExtraField &extraField) { s << extraField.customTitle; s << static_cast(extraField.flags); s << extraField.value; return s; } static QDataStream &operator>> (QDataStream &s, ExtraField &extraField) { s >> extraField.customTitle; int i; s >> i; extraField.flags = AuthInfo::FieldFlags(i); s >> extraField.value; return s; } static QDBusArgument &operator<<(QDBusArgument &argument, const ExtraField &extraField) { argument.beginStructure(); argument << extraField.customTitle << static_cast(extraField.flags) << QDBusVariant(extraField.value); argument.endStructure(); return argument; } static const QDBusArgument &operator>>(const QDBusArgument &argument, ExtraField &extraField) { QDBusVariant value; int flag; argument.beginStructure(); argument >> extraField.customTitle >> flag >> value; argument.endStructure(); extraField.value = value.variant(); extraField.flags = KIO::AuthInfo::FieldFlags(flag); return argument; } class KIO::AuthInfoPrivate { public: QMap extraFields; }; ////// AuthInfo::AuthInfo() : d(new AuthInfoPrivate()) { modified = false; readOnly = false; verifyPath = false; keepPassword = false; AuthInfo::registerMetaTypes(); } AuthInfo::AuthInfo(const AuthInfo &info) : d(new AuthInfoPrivate()) { (*this) = info; AuthInfo::registerMetaTypes(); } AuthInfo::~AuthInfo() { delete d; } AuthInfo &AuthInfo::operator= (const AuthInfo &info) { url = info.url; username = info.username; password = info.password; prompt = info.prompt; caption = info.caption; comment = info.comment; commentLabel = info.commentLabel; realmValue = info.realmValue; digestInfo = info.digestInfo; verifyPath = info.verifyPath; readOnly = info.readOnly; keepPassword = info.keepPassword; modified = info.modified; d->extraFields = info.d->extraFields; return *this; } bool AuthInfo::isModified() const { return modified; } void AuthInfo::setModified(bool flag) { modified = flag; } ///// void AuthInfo::setExtraField(const QString &fieldName, const QVariant &value) { d->extraFields[fieldName].value = value; } void AuthInfo::setExtraFieldFlags(const QString &fieldName, const FieldFlags flags) { d->extraFields[fieldName].flags = flags; } QVariant AuthInfo::getExtraField(const QString &fieldName) const { if (!d->extraFields.contains(fieldName)) { return QVariant(); } return d->extraFields[fieldName].value; } AuthInfo::FieldFlags AuthInfo::getExtraFieldFlags(const QString &fieldName) const { if (!d->extraFields.contains(fieldName)) { return AuthInfo::ExtraFieldNoFlags; } return d->extraFields[fieldName].flags; } void AuthInfo::registerMetaTypes() { qRegisterMetaType(); qRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); } ///// QDataStream &KIO::operator<< (QDataStream &s, const AuthInfo &a) { s << quint8(1) << a.url << a.username << a.password << a.prompt << a.caption << a.comment << a.commentLabel << a.realmValue << a.digestInfo << a.verifyPath << a.readOnly << a.keepPassword << a.modified << a.d->extraFields; return s; } QDataStream &KIO::operator>> (QDataStream &s, AuthInfo &a) { quint8 version; s >> version >> a.url >> a.username >> a.password >> a.prompt >> a.caption >> a.comment >> a.commentLabel >> a.realmValue >> a.digestInfo >> a.verifyPath >> a.readOnly >> a.keepPassword >> a.modified >> a.d->extraFields; return s; } QDBusArgument &KIO::operator<<(QDBusArgument &argument, const AuthInfo &a) { argument.beginStructure(); argument << quint8(1) << a.url.toString() << a.username << a.password << a.prompt << a.caption << a.comment << a.commentLabel << a.realmValue << a.digestInfo << a.verifyPath << a.readOnly << a.keepPassword << a.modified << a.d->extraFields; argument.endStructure(); return argument; } const QDBusArgument &KIO::operator>>(const QDBusArgument &argument, AuthInfo &a) { QString url; quint8 version; argument.beginStructure(); argument >> version >> url >> a.username >> a.password >> a.prompt >> a.caption >> a.comment >> a.commentLabel >> a.realmValue >> a.digestInfo >> a.verifyPath >> a.readOnly >> a.keepPassword >> a.modified >> a.d->extraFields; argument.endStructure(); a.url = QUrl(url); return argument; } typedef QList LoginList; typedef QMap LoginMap; class Q_DECL_HIDDEN NetRC::NetRCPrivate { public: NetRCPrivate() : isDirty(false), index(-1) {} QString extract(const QString &buf, const QString &key); void getMachinePart(const QString &line); void getMacdefPart(const QString &line); bool isDirty; LoginMap loginMap; QTextStream fstream; QString type; int index; }; NetRC *NetRC::instance = nullptr; NetRC::NetRC() : d(new NetRCPrivate) { } NetRC::~NetRC() { delete instance; instance = nullptr; delete d; } NetRC *NetRC::self() { if (!instance) { instance = new NetRC; } return instance; } bool NetRC::lookup(const QUrl &url, AutoLogin &login, bool userealnetrc, const QString &_type, LookUpMode mode) { //qDebug() << "AutoLogin lookup for: " << url.host(); if (!url.isValid()) { return false; } QString type = _type; if (type.isEmpty()) { type = url.scheme(); } if (d->loginMap.isEmpty() || d->isDirty) { d->loginMap.clear(); - QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + QLatin1String("kionetrc"); + QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/kionetrc"); bool kionetrcStatus = parse(filename); bool netrcStatus = false; if (userealnetrc) { filename = QDir::homePath() + QLatin1String("/.netrc"); netrcStatus = parse(filename); } if (!(kionetrcStatus || netrcStatus)) { return false; } } if (!d->loginMap.contains(type)) { return false; } const LoginList &l = d->loginMap[type]; if (l.isEmpty()) { return false; } for (LoginList::ConstIterator it = l.begin(); it != l.end(); ++it) { const AutoLogin &log = *it; if ((mode & defaultOnly) == defaultOnly && log.machine == QLatin1String("default") && (login.login.isEmpty() || login.login == log.login)) { login.type = log.type; login.machine = log.machine; login.login = log.login; login.password = log.password; login.macdef = log.macdef; } if ((mode & presetOnly) == presetOnly && log.machine == QLatin1String("preset") && (login.login.isEmpty() || login.login == log.login)) { login.type = log.type; login.machine = log.machine; login.login = log.login; login.password = log.password; login.macdef = log.macdef; } if ((mode & exactOnly) == exactOnly && log.machine == url.host() && (login.login.isEmpty() || login.login == log.login)) { login.type = log.type; login.machine = log.machine; login.login = log.login; login.password = log.password; login.macdef = log.macdef; break; } } return true; } void NetRC::reload() { d->isDirty = true; } bool NetRC::parse(const QString &fileName) { QFile file(fileName); if (file.permissions() != (QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser)) { return false; } if (!file.open(QIODevice::ReadOnly)) { return false; } d->fstream.setDevice(&file); QString line; while (!d->fstream.atEnd()) { line = d->fstream.readLine().simplified(); // If line is a comment or is empty, read next line if ((line.startsWith(QLatin1Char('#')) || line.isEmpty())) { continue; } // If line refers to a machine, maybe it is spread in more lines. // getMachinePart() will take care of getting all the info and putting it into loginMap. if ((line.startsWith(QLatin1String("machine")) || line.startsWith(QLatin1String("default")) || line.startsWith(QLatin1String("preset")))) { d->getMachinePart(line); continue; } // If line refers to a macdef, it will be more than one line. // getMacdefPart() will take care of getting all the lines of the macro // and putting them into loginMap if (line.startsWith(QLatin1String("macdef"))) { d->getMacdefPart(line); continue; } } return true; } QString NetRC::NetRCPrivate::extract(const QString &buf, const QString &key) { QStringList stringList = buf.split(QLatin1Char(' '), QString::SkipEmptyParts); int i = stringList.indexOf(key); if ((i != -1) && (i + 1 < stringList.size())) { return stringList.at(i + 1); } else { return QString(); } } void NetRC::NetRCPrivate::getMachinePart(const QString &line) { QString buf = line; while (!(buf.contains(QStringLiteral("login")) && (buf.contains(QStringLiteral("password")) || buf.contains(QStringLiteral("account")) || buf.contains(QStringLiteral("type"))))) { buf += QLatin1Char(' '); buf += fstream.readLine().simplified(); } // Once we've got all the info, process it. AutoLogin l; l.machine = extract(buf, QStringLiteral("machine")); if (l.machine.isEmpty()) { if (buf.contains(QStringLiteral("default"))) { l.machine = QStringLiteral("default"); } else if (buf.contains(QStringLiteral("preset"))) { l.machine = QStringLiteral("preset"); } } l.login = extract(buf, QStringLiteral("login")); l.password = extract(buf, QStringLiteral("password")); if (l.password.isEmpty()) { l.password = extract(buf, QStringLiteral("account")); } type = l.type = extract(buf, QStringLiteral("type")); if (l.type.isEmpty() && !l.machine.isEmpty()) { type = l.type = QStringLiteral("ftp"); } loginMap[l.type].append(l); index = loginMap[l.type].count() - 1; } void NetRC::NetRCPrivate::getMacdefPart(const QString &line) { QString buf = line; QString macro = extract(buf, QStringLiteral("macdef")); QString newLine; while (!fstream.atEnd()) { newLine = fstream.readLine().simplified(); if (!newLine.isEmpty()) { buf += QLatin1Char('\n'); buf += newLine; } else { break; } } loginMap[type][index].macdef[macro].append(buf); } diff --git a/src/core/krecentdocument.cpp b/src/core/krecentdocument.cpp index 9e6f8fa0..b26b0e8c 100644 --- a/src/core/krecentdocument.cpp +++ b/src/core/krecentdocument.cpp @@ -1,181 +1,181 @@ /* -*- c++ -*- * Copyright (C)2000 Daniel M. Duley * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "krecentdocument.h" #ifdef Q_OS_WIN #include #else #include #endif #include #include #include #include #include #include #include #include #include QString KRecentDocument::recentDocumentDirectory() { // need to change this path, not sure where - return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QLatin1String("RecentDocuments/"); + return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/RecentDocuments/"); } QStringList KRecentDocument::recentDocuments() { QDir d(recentDocumentDirectory(), QStringLiteral("*.desktop"), QDir::Time, QDir::Files | QDir::Readable | QDir::Hidden); if (!d.exists()) { d.mkdir(recentDocumentDirectory()); } const QStringList list = d.entryList(); QStringList fullList; for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { QString fileName = *it; QString pathDesktop; if (fileName.startsWith(QLatin1Char(':'))) { // See: https://bugreports.qt.io/browse/QTBUG-11223 pathDesktop = KRecentDocument::recentDocumentDirectory() + *it; } else { pathDesktop = d.absoluteFilePath(*it); } KDesktopFile tmpDesktopFile(pathDesktop); QUrl urlDesktopFile(tmpDesktopFile.desktopGroup().readPathEntry("URL", QString())); if (urlDesktopFile.isLocalFile() && !QFile(urlDesktopFile.toLocalFile()).exists()) { d.remove(pathDesktop); } else { fullList.append(pathDesktop); } } return fullList; } void KRecentDocument::add(const QUrl &url) { // desktopFileName is in QGuiApplication but we're in KIO Core here QString desktopEntryName = QCoreApplication::instance()->property("desktopFileName").toString(); if (desktopEntryName.isEmpty()) { desktopEntryName = QCoreApplication::applicationName(); } KRecentDocument::add(url, desktopEntryName); // ### componentName might not match the service filename... } void KRecentDocument::add(const QUrl &url, const QString &desktopEntryName) { if (url.isLocalFile() && url.toLocalFile().startsWith(QDir::tempPath())) { return; // inside tmp resource, do not save } QString openStr = url.toDisplayString(); openStr.replace(QRegExp(QStringLiteral("\\$")), QStringLiteral("$$")); // Desktop files with type "Link" are $-variable expanded // qDebug() << "KRecentDocument::add for " << openStr; KConfigGroup config = KSharedConfig::openConfig()->group(QByteArray("RecentDocuments")); bool useRecent = config.readEntry(QStringLiteral("UseRecent"), true); int maxEntries = config.readEntry(QStringLiteral("MaxEntries"), 10); if (!useRecent || maxEntries <= 0) { return; } const QString path = recentDocumentDirectory(); const QString fileName = url.fileName(); // don't create a file called ".desktop", it will lead to an empty name in kio_recentdocuments const QString dStr = path + (fileName.isEmpty() ? QStringLiteral("unnamed") : fileName); QString ddesktop = dStr + QLatin1String(".desktop"); int i = 1; // check for duplicates while (QFile::exists(ddesktop)) { // see if it points to the same file and application KDesktopFile tmp(ddesktop); if (tmp.desktopGroup().readPathEntry("URL", QString()) == url.toDisplayString() && tmp.desktopGroup().readEntry("X-KDE-LastOpenedWith") == desktopEntryName) { // Set access and modification time to current time ::utime(QFile::encodeName(ddesktop).constData(), nullptr); return; } // if not append a (num) to it ++i; if (i > maxEntries) { break; } ddesktop = dStr + QStringLiteral("[%1].desktop").arg(i); } QDir dir(path); // check for max entries, delete oldest files if exceeded const QStringList list = dir.entryList(QDir::Files | QDir::Hidden, QFlags(QDir::Time | QDir::Reversed)); i = list.count(); if (i > maxEntries - 1) { QStringList::ConstIterator it; it = list.begin(); while (i > maxEntries - 1) { QFile::remove(dir.absolutePath() + QLatin1Char('/') + (*it)); --i; ++it; } } // create the applnk KDesktopFile configFile(ddesktop); KConfigGroup conf = configFile.desktopGroup(); conf.writeEntry("Type", QStringLiteral("Link")); conf.writePathEntry("URL", openStr); // If you change the line below, change the test in the above loop conf.writeEntry("X-KDE-LastOpenedWith", desktopEntryName); conf.writeEntry("Name", url.fileName()); conf.writeEntry("Icon", KIO::iconNameForUrl(url)); } void KRecentDocument::clear() { const QStringList list = recentDocuments(); QDir dir; for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { dir.remove(*it); } } int KRecentDocument::maximumItems() { KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("RecentDocuments")); return cg.readEntry(QStringLiteral("MaxEntries"), 10); }