File indexing completed on 2024-05-05 03:56:07

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2004 Kevin Ottens <ervin ipsquad net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kio_remote.h"
0009 #include "debug.h"
0010 #include <stdlib.h>
0011 
0012 #include <QCoreApplication>
0013 
0014 // Pseudo plugin class to embed meta data
0015 class KIOPluginForMetaData : public QObject
0016 {
0017     Q_OBJECT
0018     Q_PLUGIN_METADATA(IID "org.kde.kio.worker.remote" FILE "remote.json")
0019 };
0020 
0021 extern "C" {
0022 int Q_DECL_EXPORT kdemain(int argc, char **argv)
0023 {
0024     // necessary to use other kio workers
0025     QCoreApplication app(argc, argv);
0026     app.setApplicationName(QStringLiteral("kio_remote"));
0027 
0028     // start the worker
0029     RemoteProtocol worker(argv[1], argv[2], argv[3]);
0030     worker.dispatchLoop();
0031     return 0;
0032 }
0033 }
0034 
0035 RemoteProtocol::RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
0036     : WorkerBase(protocol, pool, app)
0037 {
0038 }
0039 
0040 RemoteProtocol::~RemoteProtocol()
0041 {
0042 }
0043 
0044 KIO::WorkerResult RemoteProtocol::listDir(const QUrl &url)
0045 {
0046     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::listDir: " << url;
0047 
0048     if (url.path().length() <= 1) {
0049         return listRoot();
0050     }
0051 
0052     int second_slash_idx = url.path().indexOf(QLatin1Char('/'), 1);
0053     const QString root_dirname = url.path().mid(1, second_slash_idx - 1);
0054 
0055     QUrl target = m_impl.findBaseURL(root_dirname);
0056     qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
0057     if (target.isValid()) {
0058         if (second_slash_idx < 0) {
0059             second_slash_idx = url.path().size();
0060         }
0061         const QString urlPath = url.path().remove(0, second_slash_idx);
0062         if (!urlPath.isEmpty()) {
0063             target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath));
0064         }
0065         qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
0066         redirection(target);
0067         return KIO::WorkerResult::pass();
0068     }
0069 
0070     return KIO::WorkerResult::fail(KIO::ERR_MALFORMED_URL, url.toDisplayString());
0071 }
0072 
0073 KIO::WorkerResult RemoteProtocol::listRoot()
0074 {
0075     KIO::UDSEntry entry;
0076 
0077     KIO::UDSEntryList remote_entries;
0078     m_impl.listRoot(remote_entries);
0079 
0080     totalSize(remote_entries.count() + 2);
0081 
0082     m_impl.createTopLevelEntry(entry);
0083     listEntry(entry);
0084 
0085     KIO::UDSEntryList::ConstIterator it = remote_entries.constBegin();
0086     const KIO::UDSEntryList::ConstIterator end = remote_entries.constEnd();
0087     for (; it != end; ++it) {
0088         listEntry(*it);
0089     }
0090 
0091     entry.clear();
0092     return KIO::WorkerResult::pass();
0093 }
0094 
0095 KIO::WorkerResult RemoteProtocol::stat(const QUrl &url)
0096 {
0097     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::stat: " << url;
0098 
0099     QString path = url.path();
0100     if (path.isEmpty() || path == QLatin1String("/")) {
0101         // The root is "virtual" - it's not a single physical directory
0102         KIO::UDSEntry entry;
0103         m_impl.createTopLevelEntry(entry);
0104         statEntry(entry);
0105         return KIO::WorkerResult::pass();
0106     }
0107 
0108     int second_slash_idx = url.path().indexOf(QLatin1Char('/'), 1);
0109     const QString root_dirname = url.path().mid(1, second_slash_idx - 1);
0110 
0111     if (second_slash_idx == -1 || ((int)url.path().length()) == second_slash_idx + 1) {
0112         KIO::UDSEntry entry;
0113         if (m_impl.statNetworkFolder(entry, root_dirname)) {
0114             statEntry(entry);
0115             return KIO::WorkerResult::pass();
0116         }
0117     } else {
0118         QUrl target = m_impl.findBaseURL(root_dirname);
0119         qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
0120         if (target.isValid()) {
0121             if (second_slash_idx < 0) {
0122                 second_slash_idx = url.path().size();
0123             }
0124             const QString urlPath = url.path().remove(0, second_slash_idx);
0125             if (!urlPath.isEmpty()) {
0126                 target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath));
0127             }
0128             qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
0129             redirection(target);
0130             return KIO::WorkerResult::pass();
0131         }
0132     }
0133 
0134     return KIO::WorkerResult::fail(KIO::ERR_MALFORMED_URL, url.toDisplayString());
0135 }
0136 
0137 KIO::WorkerResult RemoteProtocol::del(const QUrl &url, bool /*isFile*/)
0138 {
0139     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::del: " << url;
0140 
0141     if (m_impl.deleteNetworkFolder(url.fileName())) {
0142         return KIO::WorkerResult::pass();
0143     }
0144 
0145     return KIO::WorkerResult::fail(KIO::ERR_CANNOT_DELETE, url.toDisplayString());
0146 }
0147 
0148 KIO::WorkerResult RemoteProtocol::get(const QUrl &url)
0149 {
0150     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::get: " << url;
0151 
0152     const QString file = m_impl.findDesktopFile(url.fileName());
0153     qCDebug(KIOREMOTE_LOG) << "desktop file : " << file;
0154 
0155     if (!file.isEmpty()) {
0156         redirection(QUrl::fromLocalFile(file));
0157         return KIO::WorkerResult::pass();
0158     }
0159 
0160     return KIO::WorkerResult::fail(KIO::ERR_MALFORMED_URL, url.toDisplayString());
0161 }
0162 
0163 KIO::WorkerResult RemoteProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags)
0164 {
0165     if (src.scheme() != QLatin1String("remote") || dest.scheme() != QLatin1String("remote")) {
0166         return KIO::WorkerResult::fail(KIO::ERR_UNSUPPORTED_ACTION, src.toDisplayString());
0167     }
0168 
0169     if (m_impl.renameFolders(src.fileName(), dest.fileName(), flags & KIO::Overwrite)) {
0170         return KIO::WorkerResult::pass();
0171     }
0172 
0173     return KIO::WorkerResult::fail(KIO::ERR_CANNOT_RENAME, src.toDisplayString());
0174 }
0175 
0176 KIO::WorkerResult RemoteProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags)
0177 {
0178     if (m_impl.changeFolderTarget(dest.fileName(), target, flags & KIO::Overwrite)) {
0179         return KIO::WorkerResult::pass();
0180     }
0181 
0182     return KIO::WorkerResult::fail(KIO::ERR_CANNOT_SYMLINK, dest.toDisplayString());
0183 }
0184 
0185 #include "kio_remote.moc"