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 |
15 | class KIOPluginForMetaData : public QObject |
16 | { |
17 | Q_OBJECT |
18 | Q_PLUGIN_METADATA(IID "org.kde.kio.worker.remote" FILE "remote.json" ) |
19 | }; |
20 | |
21 | extern "C" { |
22 | int 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 | |
35 | RemoteProtocol::RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app) |
36 | : WorkerBase(protocol, pool, app) |
37 | { |
38 | } |
39 | |
40 | RemoteProtocol::~RemoteProtocol() |
41 | { |
42 | } |
43 | |
44 | KIO::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 | |
73 | KIO::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 | |
95 | KIO::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 | |
137 | KIO::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 | |
148 | KIO::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 | |
163 | KIO::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 | |
176 | KIO::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 | |