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.slave.remote" FILE "remote.json")
19 };
20 
21 extern "C" {
kdemain(int argc,char ** argv)22 int Q_DECL_EXPORT kdemain(int argc, char **argv)
23 {
24     // necessary to use other kio slaves
25     QCoreApplication app(argc, argv);
26     app.setApplicationName(QStringLiteral("kio_remote"));
27 
28     // start the slave
29     RemoteProtocol slave(argv[1], argv[2], argv[3]);
30     slave.dispatchLoop();
31     return 0;
32 }
33 }
34 
RemoteProtocol(const QByteArray & protocol,const QByteArray & pool,const QByteArray & app)35 RemoteProtocol::RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app)
36     : SlaveBase(protocol, pool, app)
37 {
38 }
39 
~RemoteProtocol()40 RemoteProtocol::~RemoteProtocol()
41 {
42 }
43 
listDir(const QUrl & url)44 void RemoteProtocol::listDir(const QUrl &url)
45 {
46     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::listDir: " << url;
47 
48     if (url.path().length() <= 1) {
49         listRoot();
50         return;
51     }
52 
53     int second_slash_idx = url.path().indexOf(QLatin1Char('/'), 1);
54     const QString root_dirname = url.path().mid(1, second_slash_idx - 1);
55 
56     QUrl target = m_impl.findBaseURL(root_dirname);
57     qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
58     if (target.isValid()) {
59         if (second_slash_idx < 0) {
60             second_slash_idx = url.path().size();
61         }
62         const QString urlPath = url.path().remove(0, second_slash_idx);
63         if (!urlPath.isEmpty()) {
64             target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath));
65         }
66         qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
67         redirection(target);
68         finished();
69         return;
70     }
71 
72     error(KIO::ERR_MALFORMED_URL, url.toDisplayString());
73 }
74 
listRoot()75 void RemoteProtocol::listRoot()
76 {
77     KIO::UDSEntry entry;
78 
79     KIO::UDSEntryList remote_entries;
80     m_impl.listRoot(remote_entries);
81 
82     totalSize(remote_entries.count() + 2);
83 
84     m_impl.createTopLevelEntry(entry);
85     listEntry(entry);
86 
87     KIO::UDSEntryList::ConstIterator it = remote_entries.constBegin();
88     const KIO::UDSEntryList::ConstIterator end = remote_entries.constEnd();
89     for (; it != end; ++it) {
90         listEntry(*it);
91     }
92 
93     entry.clear();
94     finished();
95 }
96 
stat(const QUrl & url)97 void RemoteProtocol::stat(const QUrl &url)
98 {
99     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::stat: " << url;
100 
101     QString path = url.path();
102     if (path.isEmpty() || path == QLatin1String("/")) {
103         // The root is "virtual" - it's not a single physical directory
104         KIO::UDSEntry entry;
105         m_impl.createTopLevelEntry(entry);
106         statEntry(entry);
107         finished();
108         return;
109     }
110 
111     int second_slash_idx = url.path().indexOf(QLatin1Char('/'), 1);
112     const QString root_dirname = url.path().mid(1, second_slash_idx - 1);
113 
114     if (second_slash_idx == -1 || ((int)url.path().length()) == second_slash_idx + 1) {
115         KIO::UDSEntry entry;
116         if (m_impl.statNetworkFolder(entry, root_dirname)) {
117             statEntry(entry);
118             finished();
119             return;
120         }
121     } else {
122         QUrl target = m_impl.findBaseURL(root_dirname);
123         qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target;
124         if (target.isValid()) {
125             if (second_slash_idx < 0) {
126                 second_slash_idx = url.path().size();
127             }
128             const QString urlPath = url.path().remove(0, second_slash_idx);
129             if (!urlPath.isEmpty()) {
130                 target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath));
131             }
132             qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target;
133             redirection(target);
134             finished();
135             return;
136         }
137     }
138 
139     error(KIO::ERR_MALFORMED_URL, url.toDisplayString());
140 }
141 
del(const QUrl & url,bool)142 void RemoteProtocol::del(const QUrl &url, bool /*isFile*/)
143 {
144     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::del: " << url;
145 
146     if (m_impl.deleteNetworkFolder(url.fileName())) {
147         finished();
148         return;
149     }
150 
151     error(KIO::ERR_CANNOT_DELETE, url.toDisplayString());
152 }
153 
get(const QUrl & url)154 void RemoteProtocol::get(const QUrl &url)
155 {
156     qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::get: " << url;
157 
158     const QString file = m_impl.findDesktopFile(url.fileName());
159     qCDebug(KIOREMOTE_LOG) << "desktop file : " << file;
160 
161     if (!file.isEmpty()) {
162         redirection(QUrl::fromLocalFile(file));
163         finished();
164         return;
165     }
166 
167     error(KIO::ERR_MALFORMED_URL, url.toDisplayString());
168 }
169 
rename(const QUrl & src,const QUrl & dest,KIO::JobFlags flags)170 void RemoteProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags)
171 {
172     if (src.scheme() != QLatin1String("remote") || dest.scheme() != QLatin1String("remote")) {
173         error(KIO::ERR_UNSUPPORTED_ACTION, src.toDisplayString());
174         return;
175     }
176 
177     if (m_impl.renameFolders(src.fileName(), dest.fileName(), flags & KIO::Overwrite)) {
178         finished();
179         return;
180     }
181 
182     error(KIO::ERR_CANNOT_RENAME, src.toDisplayString());
183 }
184 
symlink(const QString & target,const QUrl & dest,KIO::JobFlags flags)185 void RemoteProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags)
186 {
187     if (m_impl.changeFolderTarget(dest.fileName(), target, flags & KIO::Overwrite)) {
188         finished();
189         return;
190     }
191 
192     error(KIO::ERR_CANNOT_SYMLINK, dest.toDisplayString());
193 }
194 
195 #include "kio_remote.moc"
196