diff --git a/src/ioslaves/CMakeLists.txt b/src/ioslaves/CMakeLists.txt --- a/src/ioslaves/CMakeLists.txt +++ b/src/ioslaves/CMakeLists.txt @@ -5,5 +5,6 @@ add_subdirectory( ftp ) add_subdirectory( telnet ) add_subdirectory( trash ) +add_subdirectory( remote ) add_subdirectory( protocols ) diff --git a/src/ioslaves/remote/CMakeLists.txt b/src/ioslaves/remote/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/CMakeLists.txt @@ -0,0 +1,19 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"kio_remote\") + +add_subdirectory( kdedmodule ) + +set(kio_remote_SRCS + kio_remote.cpp + remoteimpl.cpp + ) + +ecm_qt_declare_logging_category(kio_remote_SRCS HEADER debug.h + IDENTIFIER KIOREMOTE_LOG + CATEGORY_NAME log_kioremote + DEFAULT_SEVERITY Info) + +add_library(kio_remote MODULE ${kio_remote_SRCS}) +target_link_libraries(kio_remote KF5::KIOCore KF5::I18n) + +install(TARGETS kio_remote DESTINATION ${KDE_INSTALL_PLUGINDIR} ) +install( FILES remote.protocol DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/src/ioslaves/remote/Messages.sh b/src/ioslaves/remote/Messages.sh new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $podir/kio_remote.pot diff --git a/src/ioslaves/remote/kdedmodule/CMakeLists.txt b/src/ioslaves/remote/kdedmodule/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(remotedirnotify MODULE remotedirnotify.cpp remotedirnotifymodule.cpp ../debug.cpp) +kcoreaddons_desktop_to_json(remotedirnotify remotedirnotify.desktop) + +target_link_libraries(remotedirnotify KF5::DBusAddons KF5::KIOCore) + +install(TARGETS remotedirnotify DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kded ) diff --git a/src/ioslaves/remote/kdedmodule/remotedirnotify.h b/src/ioslaves/remote/kdedmodule/remotedirnotify.h new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/remotedirnotify.h @@ -0,0 +1,40 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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. +*/ + +#ifndef REMOTEDIRNOTIFY_H +#define REMOTEDIRNOTIFY_H + +#include + +class KDirWatch; + +class RemoteDirNotify : public QObject +{ + Q_OBJECT + +public: + RemoteDirNotify(); + +private slots: + void slotRemoteChanged(); + +private: + KDirWatch *m_dirWatch; +}; + +#endif diff --git a/src/ioslaves/remote/kdedmodule/remotedirnotify.cpp b/src/ioslaves/remote/kdedmodule/remotedirnotify.cpp new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/remotedirnotify.cpp @@ -0,0 +1,42 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 "remotedirnotify.h" + +#include +#include + +#include +#include + +RemoteDirNotify::RemoteDirNotify() +{ + const QString path = QStringLiteral("%1/remoteview").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); + + m_dirWatch = new KDirWatch(this); + m_dirWatch->addDir(path, KDirWatch::WatchFiles); + + connect(m_dirWatch, &KDirWatch::created, this, &RemoteDirNotify::slotRemoteChanged); + connect(m_dirWatch, &KDirWatch::deleted, this, &RemoteDirNotify::slotRemoteChanged); + connect(m_dirWatch, &KDirWatch::dirty, this, &RemoteDirNotify::slotRemoteChanged); +} + +void RemoteDirNotify::slotRemoteChanged() +{ + org::kde::KDirNotify::emitFilesAdded(QUrl("remote:/")); +} diff --git a/src/ioslaves/remote/kdedmodule/remotedirnotify.desktop b/src/ioslaves/remote/kdedmodule/remotedirnotify.desktop new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/remotedirnotify.desktop @@ -0,0 +1,105 @@ +[Desktop Entry] +Type=Service +Name=Remote URL Change Notifier +Name[bs]=Udaljeni URL izvještavač o promjenama +Name[ca]=Notificador de canvi d'URL remot +Name[ca@valencia]=Notificador de canvi d'URL remot +Name[cs]=Démon upozorňování na vzdálená URL +Name[da]=Bekendtgørelse af ændring på eksterne URL'er +Name[de]=Überwachung für Dateien auf Fremdrechnern +Name[el]=Εργαλείο ειδοποιήσεων αλλαγής απομακρυσμένου URL +Name[en_GB]=Remote URL Change Notifier +Name[es]=Notificador de cambios en URL remotos +Name[et]=Mujalasuva URL-i muutumise teadustaja +Name[eu]=Urruneko URL aldaketa jakinarazlea +Name[fi]=Etäverkko-osoitteiden muutosten ilmoitin +Name[fr]=Avertisseur de changement d'URL distante +Name[gl]=Notificador de cambios en URL remotas +Name[he]=מעקב אחר שינויים בכתובת מרוחקת +Name[hr]=Glasnik promjena na udaljenom URL-u +Name[hu]=Távoli URL-címváltozás értesítő +Name[ia]=Notificator remote de cambio de URL +Name[id]=Notifikasi Ubah URL Jarak Jauh +Name[is]=Tilkynningar á slóðabreytingum (URL) +Name[it]=Notificatore del cambiamento dell'URL remoto +Name[ja]=リモート URL 変更通知 +Name[ko]=원격 URL 변경 알림이 +Name[lt]=Nutolusio URL pasikeitimo priminimo programa +Name[nb]=Påminner for endringer i eksterne URL-er +Name[nds]=Feern-URL-Ännernbescheed +Name[nl]=Notificatie van wijziging in URL-adres op afstand +Name[nn]=Varsling for endringar på nettadresser +Name[pl]=Powiadamianie o zmianie zdalnego adresu URL +Name[pt]=Notificador da Alteração de URLs Remotos +Name[pt_BR]=Notificador da alteração de URLs remotas +Name[ru]=Слежение за изменениями URL +Name[sk]=Monitor zmien vzdialených URL +Name[sl]=Obvestilnik sprememb oddaljenega URL-ja +Name[sr]=Извештавач о изменама удаљених УРЛ‑ова +Name[sr@ijekavian]=Извјештавач о изменама удаљених УРЛ‑ова +Name[sr@ijekavianlatin]=Izvještavač o izmenama udaljenih URL‑ova +Name[sr@latin]=Izveštavač o izmenama udaljenih URL‑ova +Name[sv]=Underrättelse om ändring av fjärrwebbadresser +Name[tr]=Uzak Adres Değiştirme Bildiricisi +Name[uk]=Сповіщення про зміну віддаленої адреси (URL) +Name[x-test]=xxRemote URL Change Notifierxx +Name[zh_CN]=远程 URL 更改通知器 +Name[zh_TW]=遠端網址變更通知程式 +Comment=Provides change notification for network folders +Comment[bn]=নেটওয়ার্ক ফোল্ডার-এ পরিবর্তনের সূচনা দেয় +Comment[bs]=Ispostavlja obavještenja o izmjenama u mrežnim fasciklama +Comment[ca]=Proporciona notificacions de canvis en carpetes de xarxa +Comment[ca@valencia]=Proporciona notificacions de canvis en carpetes de xarxa +Comment[cs]=Poskytuje oznamování o změnách síťových složek +Comment[da]=Giver bekendtgørelse af ændringer af netværksmapper +Comment[de]=Benachrichtigt den Anwender über Änderungen an Dateien in Netzwerkordnern. +Comment[el]=Παρέχει ειδοποίηση αλλαγών για δικτυακούς φακέλους +Comment[en_GB]=Provides change notification for network folders +Comment[eo]=Ĝi provizas atentigojn pri ŝanĝoj de retaj dosierujoj +Comment[es]=Proporciona notificaciones sobre cambios en carpetas de red +Comment[et]=Võrgukataloogide muutuste märguanded +Comment[eu]=Sareko karpeten aldaketa jakinarazpenak ematen ditu +Comment[fa]=هشدار تغییر را برای پوشه‌های شبکه ارائه میدهد +Comment[fi]=Tarjoaa ilmoituksia verkkokansioiden muutoksista +Comment[fr]=Fournit les notifications de modification pour les dossiers du réseau +Comment[ga]=Cuireann sé in iúl duit nuair a athraíonn fillteán líonra +Comment[gl]=Fornece notificacións dos cambios en cartafoles en rede +Comment[gu]=નેટવર્ક ફોલ્ડરો માટે ફેરફાર નોંધણી પૂરી પાડે છે +Comment[he]=מתריע על שינויים בתיקיות רשת +Comment[hi]=संजाल फ़ोल्डर्स के लिए परिवर्तन अधिसूचना प्रदान करता है +Comment[hr]=Omogućuje obavještavanje o promjenama na mrežnim mapama +Comment[hu]=Értesítést küld a hálózati mappák változásairól +Comment[ia]=Il forni notification de cambio pro dossieres de rete +Comment[id]=Menyediakan notifikasi perubahan untuk folder jaringan +Comment[is]=Tilkynningaforrit fyrir breytingar á fjartengdum netmöppum +Comment[it]=Fornisce notifiche di modifica per le cartelle di rete +Comment[ja]=ネットワークフォルダの変更通知を提供します +Comment[ko]=네트워크 폴더의 변경 사항 알림 +Comment[lt]=Pranešimai naudotojui apie pasikeitimus tinklo aplankuose +Comment[nb]=Gir endringsvarslinger for nettverksmapper +Comment[nds]=Stellt Bescheden över Ännern vun Nettwarkornern praat +Comment[nl]=Levert notificatie voor wijzigingen in netwerkmappen +Comment[nn]=Gjev endringsvarslingar for nettverksmapper +Comment[pa]=ਨੈੱਟਵਰਕ ਫੋਲਡਰਾਂ ਲਈ ਤਬਦੀਲੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਦਿੰਦਾ ਹੈ +Comment[pl]=Udostępnia powiadomienia o zmianach w katalogach sieciowych +Comment[pt]=Fornece notificações de alterações para as pastas de rede +Comment[pt_BR]=Fornece notificações de alterações para pastas de rede +Comment[ru]=Отслеживание изменений в сетевых папках +Comment[sk]=Poskytuje upozornenia o zmenách sieťových priečinkov +Comment[sl]=Ponuja obvestila o spremembah omrežnih map +Comment[sr]=Даје обавештења о изменама за мрежне фасцикле +Comment[sr@ijekavian]=Даје обавјештења о изменама за мрежне фасцикле +Comment[sr@ijekavianlatin]=Daje obavještenja o izmenama za mrežne fascikle +Comment[sr@latin]=Daje obaveštenja o izmenama za mrežne fascikle +Comment[sv]=Tillhandahåller ändringsunderrättelser för nätverkskataloger +Comment[tr]=Ağ klasörleri için değişiklik bildirimleri sağlar +Comment[uk]=Сповіщення про зміну стану мережевих тек +Comment[vi]=Cung cấp thông báo thay đổi cho các thư mục mạng +Comment[x-test]=xxProvides change notification for network foldersxx +Comment[zh_CN]=为网络文件夹提供更改通知 +Comment[zh_TW]=提供網路資料夾的變更通知 +X-KDE-ServiceTypes=KDEDModule +X-KDE-Library=remotedirnotify +X-KDE-DBus-ModuleName=remotedirnotify +X-KDE-Kded-load-on-demand=true +X-KDE-Kded-autoload=true diff --git a/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.h b/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.h new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.h @@ -0,0 +1,35 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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. +*/ + +#ifndef REMOTEDIRNOTIFYMODULE_H +#define REMOTEDIRNOTIFYMODULE_H + +#include + +#include "remotedirnotify.h" + +class RemoteDirNotifyModule : public KDEDModule +{ + Q_OBJECT +public: + RemoteDirNotifyModule(QObject *parent, const QList &); +private: + RemoteDirNotify notifier; +}; + +#endif diff --git a/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.cpp b/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.cpp new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kdedmodule/remotedirnotifymodule.cpp @@ -0,0 +1,33 @@ +/* This file is part of the KDE Project + Copyright (c) 2004 Kévin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + 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 "remotedirnotifymodule.h" + +#include +//#include + +K_PLUGIN_FACTORY_WITH_JSON(RemoteDirNotifyFactory, + "remotedirnotify.json", + registerPlugin();) + +RemoteDirNotifyModule::RemoteDirNotifyModule(QObject *parent, const QList &) + : KDEDModule(parent) +{ +} + +#include "remotedirnotifymodule.moc" diff --git a/src/ioslaves/remote/kio_remote.h b/src/ioslaves/remote/kio_remote.h new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kio_remote.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + 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. +*/ + +#ifndef KIO_REMOTE_H +#define KIO_REMOTE_H + +#include +#include "remoteimpl.h" + +class RemoteProtocol : public KIO::SlaveBase +{ +public: + RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app); + ~RemoteProtocol() override; + void listDir(const QUrl &url) override; + void stat(const QUrl &url) override; + void del(const QUrl &url, bool isFile) override; + void get(const QUrl &url) override; + void rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) override; + void symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags) override; + +private: + void listRoot(); + + RemoteImpl m_impl; +}; + +#endif diff --git a/src/ioslaves/remote/kio_remote.cpp b/src/ioslaves/remote/kio_remote.cpp new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/kio_remote.cpp @@ -0,0 +1,216 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + 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 "kio_remote.h" +#include "debug.h" +#include + +#include + +extern "C" { +int Q_DECL_EXPORT kdemain(int argc, char **argv) +{ + // necessary to use other kio slaves + QCoreApplication app(argc, argv); + app.setApplicationName("kio_remote"); + + // start the slave + RemoteProtocol slave(argv[1], argv[2], argv[3]); + slave.dispatchLoop(); + return 0; +} +} + +RemoteProtocol::RemoteProtocol(const QByteArray &protocol, const QByteArray &pool, + const QByteArray &app) + : SlaveBase(protocol, pool, app) +{ +} + +RemoteProtocol::~RemoteProtocol() +{ +} + +void RemoteProtocol::listDir(const QUrl &url) +{ + qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::listDir: " << url; + + if (url.path().length() <= 1) { + listRoot(); + return; + } + + int second_slash_idx = url.path().indexOf('/', 1); + const QString root_dirname = url.path().mid(1, second_slash_idx-1); + + QUrl target = m_impl.findBaseURL(root_dirname); + qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target; + if (target.isValid()) { + if (second_slash_idx < 0) { + second_slash_idx = url.path().size(); + } + const QString urlPath = url.path().remove(0, second_slash_idx); + if (!urlPath.isEmpty()) { + target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath)); + } + qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target; + redirection(target); + finished(); + return; + } + + error(KIO::ERR_MALFORMED_URL, url.toDisplayString()); +} + +void RemoteProtocol::listRoot() +{ + KIO::UDSEntry entry; + + KIO::UDSEntryList remote_entries; + m_impl.listRoot(remote_entries); + + totalSize(remote_entries.count()+2); + + m_impl.createTopLevelEntry(entry); + listEntry(entry); + + if (m_impl.createWizardEntry(entry)) { + listEntry(entry); + } + + KIO::UDSEntryList::ConstIterator it = remote_entries.constBegin(); + const KIO::UDSEntryList::ConstIterator end = remote_entries.constEnd(); + for (; it != end; ++it) { + listEntry(*it); + } + + entry.clear(); + finished(); +} + +void RemoteProtocol::stat(const QUrl &url) +{ + qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::stat: " << url; + + QString path = url.path(); + if (path.isEmpty() || path == QLatin1String("/")) { + // The root is "virtual" - it's not a single physical directory + KIO::UDSEntry entry; + m_impl.createTopLevelEntry(entry); + statEntry(entry); + finished(); + return; + } + + if (m_impl.isWizardURL(url)) { + KIO::UDSEntry entry; + if (m_impl.createWizardEntry(entry)) { + statEntry(entry); + finished(); + } else { + error(KIO::ERR_DOES_NOT_EXIST, url.toDisplayString()); + } + return; + } + + int second_slash_idx = url.path().indexOf('/', 1); + const QString root_dirname = url.path().mid(1, second_slash_idx-1); + + if (second_slash_idx == -1 || ((int)url.path().length()) == second_slash_idx+1) { + KIO::UDSEntry entry; + if (m_impl.statNetworkFolder(entry, root_dirname)) { + statEntry(entry); + finished(); + return; + } + } else { + QUrl target = m_impl.findBaseURL(root_dirname); + qCDebug(KIOREMOTE_LOG) << "possible redirection target : " << target; + if (target.isValid()) { + if (second_slash_idx < 0) { + second_slash_idx = url.path().size(); + } + const QString urlPath = url.path().remove(0, second_slash_idx); + if (!urlPath.isEmpty()) { + target.setPath(QStringLiteral("%1/%2").arg(target.path(), urlPath)); + } + qCDebug(KIOREMOTE_LOG) << "complete redirection target : " << target; + redirection(target); + finished(); + return; + } + } + + error(KIO::ERR_MALFORMED_URL, url.toDisplayString()); +} + +void RemoteProtocol::del(const QUrl &url, bool /*isFile*/) +{ + qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::del: " << url; + + if (!m_impl.isWizardURL(url) + && m_impl.deleteNetworkFolder(url.fileName())) { + finished(); + return; + } + + error(KIO::ERR_CANNOT_DELETE, url.toDisplayString()); +} + +void RemoteProtocol::get(const QUrl &url) +{ + qCDebug(KIOREMOTE_LOG) << "RemoteProtocol::get: " << url; + + const QString file = m_impl.findDesktopFile(url.fileName()); + qCDebug(KIOREMOTE_LOG) << "desktop file : " << file; + + if (!file.isEmpty()) { + redirection(QUrl::fromLocalFile(file)); + finished(); + return; + } + + error(KIO::ERR_MALFORMED_URL, url.toDisplayString()); +} + +void RemoteProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) +{ + if (src.scheme() != QLatin1String("remote") || dest.scheme() != QLatin1String("remote") + || m_impl.isWizardURL(src) || m_impl.isWizardURL(dest)) { + error(KIO::ERR_UNSUPPORTED_ACTION, src.toDisplayString()); + return; + } + + if (m_impl.renameFolders(src.fileName(), dest.fileName(), flags & KIO::Overwrite)) { + finished(); + return; + } + + error(KIO::ERR_CANNOT_RENAME, src.toDisplayString()); +} + +void RemoteProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags) +{ + if (m_impl.changeFolderTarget(dest.fileName(), target, flags & KIO::Overwrite)) { + finished(); + return; + } + + error(KIO::ERR_CANNOT_SYMLINK, dest.toDisplayString()); +} diff --git a/src/ioslaves/remote/remote.protocol b/src/ioslaves/remote/remote.protocol new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/remote.protocol @@ -0,0 +1,17 @@ +[Protocol] +exec=kio_remote +protocol=remote +input=none +output=filesystem +listing=Name,Type,Size,Date,AccessDate,Access,Owner,Group,Link +reading=true +writing=false +makedir=false +deleting=true +linking=true +moving=true +Icon=folder-remote +maxInstances=4 +#TODO DocPath=kioslave/file.html +Class=:local +deleteRecursive=true diff --git a/src/ioslaves/remote/remoteimpl.h b/src/ioslaves/remote/remoteimpl.h new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/remoteimpl.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + 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. +*/ + +#ifndef REMOTEIMPL_H +#define REMOTEIMPL_H + +#include +#include + +class RemoteImpl +{ +public: + RemoteImpl(); + + void createTopLevelEntry(KIO::UDSEntry &entry) const; + bool createWizardEntry(KIO::UDSEntry &entry) const; + bool isWizardURL(const QUrl &url) const; + bool statNetworkFolder(KIO::UDSEntry &entry, const QString &filename) const; + + void listRoot(KIO::UDSEntryList &list) const; + + QUrl findBaseURL(const QString &filename) const; + QString findDesktopFile(const QString &filename) const; + + bool deleteNetworkFolder(const QString &filename) const; + bool renameFolders(const QString &src, const QString &dest, bool overwrite) const; + bool changeFolderTarget(const QString &src, const QString &target, bool overwrite) const; + +private: + bool findDirectory(const QString &filename, QString &directory) const; + void createEntry(KIO::UDSEntry &entry, const QString &directory, const QString &file) const; +}; + +#endif diff --git a/src/ioslaves/remote/remoteimpl.cpp b/src/ioslaves/remote/remoteimpl.cpp new file mode 100644 --- /dev/null +++ b/src/ioslaves/remote/remoteimpl.cpp @@ -0,0 +1,287 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + 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 "remoteimpl.h" + +#include "debug.h" +#include +#include +#include +#include + +#include +#include + +#include + +#define WIZARD_URL "remote:/x-wizard_service.desktop" +#define WIZARD_SERVICE "org.kde.knetattach" + +RemoteImpl::RemoteImpl() +{ + const QString path = QStringLiteral("%1/remoteview").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); + + QDir dir = path; + if (!dir.exists()) { + dir.cdUp(); + dir.mkdir(QStringLiteral("remoteview")); + } +} + +void RemoteImpl::listRoot(KIO::UDSEntryList &list) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::listRoot"; + + QStringList names_found; + const QStringList dirList = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("remoteview"), + QStandardPaths::LocateDirectory); + + QStringList::ConstIterator dirpath = dirList.constBegin(); + const QStringList::ConstIterator end = dirList.constEnd(); + for (; dirpath != end; ++dirpath) { + QDir dir = *dirpath; + if (!dir.exists()) { + continue; + } + + const QStringList filenames = dir.entryList(QDir::Files | QDir::Readable); + + KIO::UDSEntry entry; + + QStringList::ConstIterator name = filenames.constBegin(); + QStringList::ConstIterator endf = filenames.constEnd(); + + for (; name != endf; ++name) { + if (!names_found.contains(*name)) { + entry.clear(); + createEntry(entry, *dirpath, *name); + list.append(entry); + names_found.append(*name); + } + } + } +} + +bool RemoteImpl::findDirectory(const QString &filename, QString &directory) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::findDirectory"; + + const QStringList dirList = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("remoteview"), + QStandardPaths::LocateDirectory); + + QStringList::ConstIterator dirpath = dirList.constBegin(); + const QStringList::ConstIterator end = dirList.constEnd(); + for (; dirpath != end; ++dirpath) { + QDir dir = *dirpath; + if (!dir.exists()) { + continue; + } + + QStringList filenames = dir.entryList(QDir::Files | QDir::Readable); + + QStringList::ConstIterator name = filenames.constBegin(); + QStringList::ConstIterator endf = filenames.constEnd(); + + for (; name != endf; ++name) { + if (*name == filename) { + directory = *dirpath + QLatin1Char('/'); + return true; + } + } + } + + return false; +} + +QString RemoteImpl::findDesktopFile(const QString &filename) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::findDesktopFile"; + + QString directory; + if (findDirectory(filename+".desktop", directory)) { + return directory+filename+".desktop"; + } + + return QString(); +} + +QUrl RemoteImpl::findBaseURL(const QString &filename) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::findBaseURL"; + + const QString file = findDesktopFile(filename); + if (!file.isEmpty()) { + KDesktopFile desktop(file); + return QUrl::fromUserInput(desktop.readUrl()); + } + + return QUrl(); +} + +void RemoteImpl::createTopLevelEntry(KIO::UDSEntry &entry) const +{ + entry.clear(); + entry.insert(KIO::UDSEntry::UDS_NAME, QString::fromLatin1(".")); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); + entry.insert(KIO::UDSEntry::UDS_ACCESS, 0777); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1("inode/directory")); + entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QString::fromLatin1("folder-remote")); + entry.insert(KIO::UDSEntry::UDS_USER, QString::fromLatin1("root")); + entry.insert(KIO::UDSEntry::UDS_GROUP, QString::fromLatin1("root")); +} + +static QUrl findWizardRealURL() +{ + QUrl url; + KService::Ptr service = KService::serviceByDesktopName(WIZARD_SERVICE); + + if (service && service->isValid()) { + url.setPath(QStandardPaths::locate(QStandardPaths::ApplicationsLocation, + QStringLiteral("%1.desktop").arg(WIZARD_SERVICE))); + } + + return url; +} + +bool RemoteImpl::createWizardEntry(KIO::UDSEntry &entry) const +{ + entry.clear(); + + QUrl url = findWizardRealURL(); + + if (!url.isValid()) { + return false; + } + + entry.insert(KIO::UDSEntry::UDS_NAME, i18n("Add Network Folder")); + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); + entry.insert(KIO::UDSEntry::UDS_URL, QString::fromLatin1(WIZARD_URL)); + entry.insert(KIO::UDSEntry::UDS_LOCAL_PATH, url.path()); + entry.insert(KIO::UDSEntry::UDS_ACCESS, 0500); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1("application/x-desktop")); + entry.insert(KIO::UDSEntry::UDS_ICON_NAME, QString::fromLatin1("folder-new")); + + return true; +} + +bool RemoteImpl::isWizardURL(const QUrl &url) const +{ + return url == QUrl(WIZARD_URL); +} + +void RemoteImpl::createEntry(KIO::UDSEntry &entry, const QString &directory, + const QString &file) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::createEntry"; + + QString dir = directory; + if (!dir.endsWith(QLatin1Char('/'))) { + dir += QLatin1Char('/'); + } + KDesktopFile desktop(dir + file); + + qCDebug(KIOREMOTE_LOG) << "path = " << directory << file; + + entry.clear(); + + QString new_filename = file; + new_filename.truncate(file.length()-8); + + entry.insert(KIO::UDSEntry::UDS_NAME, desktop.readName()); + entry.insert(KIO::UDSEntry::UDS_URL, "remote:/"+new_filename); + + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); + entry.insert(KIO::UDSEntry::UDS_ACCESS, 0500); + entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QString::fromLatin1("inode/directory")); + + const QString icon = desktop.readIcon(); + entry.insert(KIO::UDSEntry::UDS_ICON_NAME, icon); + entry.insert(KIO::UDSEntry::UDS_LINK_DEST, desktop.readUrl()); + entry.insert(KIO::UDSEntry::UDS_TARGET_URL, desktop.readUrl()); +} + +bool RemoteImpl::statNetworkFolder(KIO::UDSEntry &entry, const QString &filename) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::statNetworkFolder: " << filename; + + QString directory; + if (findDirectory(filename+".desktop", directory)) { + createEntry(entry, directory, filename+".desktop"); + return true; + } + + return false; +} + +bool RemoteImpl::deleteNetworkFolder(const QString &filename) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::deleteNetworkFolder: " << filename; + + QString directory; + if (findDirectory(filename+".desktop", directory)) { + qCDebug(KIOREMOTE_LOG) << "Removing " << directory << filename << ".desktop"; + return QFile::remove(directory+filename+".desktop"); + } + + return false; +} + +bool RemoteImpl::renameFolders(const QString &src, const QString &dest, bool overwrite) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::renameFolders: " + << src << ", " << dest << endl; + + QString directory; + if (findDirectory(src+".desktop", directory)) { + if (!overwrite && QFile::exists(directory+dest+".desktop")) { + return false; + } + + qCDebug(KIOREMOTE_LOG) << "Renaming " << directory << src << ".desktop"; + QDir dir(directory); + bool res = dir.rename(src+".desktop", dest+".desktop"); + if (res) { + KDesktopFile desktop(directory+dest+".desktop"); + desktop.desktopGroup().writeEntry("Name", dest); + } + return res; + } + + return false; +} + +bool RemoteImpl::changeFolderTarget(const QString &src, const QString &target, bool overwrite) const +{ + qCDebug(KIOREMOTE_LOG) << "RemoteImpl::changeFolderTarget: " + << src << ", " << target << endl; + + QString directory; + if (findDirectory(src+".desktop", directory)) { + if (!overwrite || !QFile::exists(directory+src+".desktop")) { + return false; + } + + qCDebug(KIOREMOTE_LOG) << "Changing target " << directory << src << ".desktop"; + KDesktopFile desktop(directory+src+".desktop"); + desktop.desktopGroup().writeEntry("URL", target); + return true; + } + + return false; +}