1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2004 Kevin Ottens <ervin ipsquad net>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "kio_remote.h"
9#include "debug.h"
10#include <stdlib.h>
11
12#include <QCoreApplication>
13
14// Pseudo plugin class to embed meta data
15class KIOPluginForMetaData : public QObject
16{
17 Q_OBJECT
18 Q_PLUGIN_METADATA(IID "org.kde.kio.worker.remote" FILE "remote.json")
19};
20
21extern "C" {
22int Q_DECL_EXPORT kdemain(int argc, char **argv)
23{
24 // necessary to use other kio workers
25 QCoreApplication app(argc, argv);
26 app.setApplicationName(QStringLiteral("kio_remote"));
27
28 // start the worker
29 RemoteProtocol worker(argv[1], argv[2], argv[3]);
30 worker.dispatchLoop();
31 return 0;
32}
33}
34
35RemoteProtocol::RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
36 : WorkerBase(protocol, pool, app)
37{
38}
39
40RemoteProtocol::~RemoteProtocol()
41{
42}
43
44KIO::WorkerResult RemoteProtocol::listDir(const QUrl &url)
45{
46 qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::listDir: " << url;
47
48 if (url.path().length() <= 1) {
49 return listRoot();
50 }
51
52 int second_slash_idx = url.path().indexOf(c: QLatin1Char('/'), from: 1);
53 const QString root_dirname = url.path().mid(position: 1, n: second_slash_idx - 1);
54
55 QUrl target = m_impl.findBaseURL(filename: root_dirname);
56 qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
57 if (target.isValid()) {
58 if (second_slash_idx < 0) {
59 second_slash_idx = url.path().size();
60 }
61 const QString urlPath = url.path().remove(i: 0, len: second_slash_idx);
62 if (!urlPath.isEmpty()) {
63 target.setPath(QStringLiteral("%1/%2").arg(args: target.path(), args: urlPath));
64 }
65 qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
66 redirection(url: target);
67 return KIO::WorkerResult::pass();
68 }
69
70 return KIO::WorkerResult::fail(error: KIO::ERR_MALFORMED_URL, errorString: url.toDisplayString());
71}
72
73KIO::WorkerResult RemoteProtocol::listRoot()
74{
75 KIO::UDSEntry entry;
76
77 KIO::UDSEntryList remote_entries;
78 m_impl.listRoot(list&: remote_entries);
79
80 totalSize(bytes: remote_entries.count() + 2);
81
82 m_impl.createTopLevelEntry(entry);
83 listEntry(entry);
84
85 KIO::UDSEntryList::ConstIterator it = remote_entries.constBegin();
86 const KIO::UDSEntryList::ConstIterator end = remote_entries.constEnd();
87 for (; it != end; ++it) {
88 listEntry(entry: *it);
89 }
90
91 entry.clear();
92 return KIO::WorkerResult::pass();
93}
94
95KIO::WorkerResult RemoteProtocol::stat(const QUrl &url)
96{
97 qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::stat: " << url;
98
99 QString path = url.path();
100 if (path.isEmpty() || path == QLatin1String("/")) {
101 // The root is "virtual" - it's not a single physical directory
102 KIO::UDSEntry entry;
103 m_impl.createTopLevelEntry(entry);
104 statEntry(entry: entry);
105 return KIO::WorkerResult::pass();
106 }
107
108 int second_slash_idx = url.path().indexOf(c: QLatin1Char('/'), from: 1);
109 const QString root_dirname = url.path().mid(position: 1, n: second_slash_idx - 1);
110
111 if (second_slash_idx == -1 || ((int)url.path().length()) == second_slash_idx + 1) {
112 KIO::UDSEntry entry;
113 if (m_impl.statNetworkFolder(entry, filename: root_dirname)) {
114 statEntry(entry: entry);
115 return KIO::WorkerResult::pass();
116 }
117 } else {
118 QUrl target = m_impl.findBaseURL(filename: root_dirname);
119 qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
120 if (target.isValid()) {
121 if (second_slash_idx < 0) {
122 second_slash_idx = url.path().size();
123 }
124 const QString urlPath = url.path().remove(i: 0, len: second_slash_idx);
125 if (!urlPath.isEmpty()) {
126 target.setPath(QStringLiteral("%1/%2").arg(args: target.path(), args: urlPath));
127 }
128 qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
129 redirection(url: target);
130 return KIO::WorkerResult::pass();
131 }
132 }
133
134 return KIO::WorkerResult::fail(error: KIO::ERR_MALFORMED_URL, errorString: url.toDisplayString());
135}
136
137KIO::WorkerResult RemoteProtocol::del(const QUrl &url, bool /*isFile*/)
138{
139 qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::del: " << url;
140
141 if (m_impl.deleteNetworkFolder(filename: url.fileName())) {
142 return KIO::WorkerResult::pass();
143 }
144
145 return KIO::WorkerResult::fail(error: KIO::ERR_CANNOT_DELETE, errorString: url.toDisplayString());
146}
147
148KIO::WorkerResult RemoteProtocol::get(const QUrl &url)
149{
150 qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::get: " << url;
151
152 const QString file = m_impl.findDesktopFile(filename: url.fileName());
153 qCDebug(KIOREMOTE_LOG) << "desktop file : " << file;
154
155 if (!file.isEmpty()) {
156 redirection(url: QUrl::fromLocalFile(localfile: file));
157 return KIO::WorkerResult::pass();
158 }
159
160 return KIO::WorkerResult::fail(error: KIO::ERR_MALFORMED_URL, errorString: url.toDisplayString());
161}
162
163KIO::WorkerResult RemoteProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags)
164{
165 if (src.scheme() != QLatin1String("remote") || dest.scheme() != QLatin1String("remote")) {
166 return KIO::WorkerResult::fail(error: KIO::ERR_UNSUPPORTED_ACTION, errorString: src.toDisplayString());
167 }
168
169 if (m_impl.renameFolders(src: src.fileName(), dest: dest.fileName(), overwrite: flags & KIO::Overwrite)) {
170 return KIO::WorkerResult::pass();
171 }
172
173 return KIO::WorkerResult::fail(error: KIO::ERR_CANNOT_RENAME, errorString: src.toDisplayString());
174}
175
176KIO::WorkerResult RemoteProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags)
177{
178 if (m_impl.changeFolderTarget(src: dest.fileName(), target, overwrite: flags & KIO::Overwrite)) {
179 return KIO::WorkerResult::pass();
180 }
181
182 return KIO::WorkerResult::fail(error: KIO::ERR_CANNOT_SYMLINK, errorString: dest.toDisplayString());
183}
184
185#include "kio_remote.moc"
186

source code of kio/src/kioworkers/remote/kio_remote.cpp