summaryrefslogtreecommitdiffstats
path: root/kioslave/trash
diff options
context:
space:
mode:
Diffstat (limited to 'kioslave/trash')
-rw-r--r--kioslave/trash/CMakeLists.txt59
-rw-r--r--kioslave/trash/DESIGN53
-rw-r--r--kioslave/trash/Makefile.am31
-rw-r--r--kioslave/trash/kfile-plugin/CMakeLists.txt38
-rw-r--r--kioslave/trash/kfile-plugin/Makefile.am14
-rw-r--r--kioslave/trash/kfile-plugin/RETURNED_ITEMS4
-rw-r--r--kioslave/trash/kfile-plugin/kfile_trash.cpp93
-rw-r--r--kioslave/trash/kfile-plugin/kfile_trash.desktop79
-rw-r--r--kioslave/trash/kfile-plugin/kfile_trash.h42
-rw-r--r--kioslave/trash/kfile-plugin/kfile_trash_system.desktop79
-rw-r--r--kioslave/trash/kio_trash.cpp596
-rw-r--r--kioslave/trash/kio_trash.h71
-rw-r--r--kioslave/trash/ktrash.cpp102
-rw-r--r--kioslave/trash/testtrash.cpp1198
-rw-r--r--kioslave/trash/testtrash.h118
-rw-r--r--kioslave/trash/trash.protocol89
-rw-r--r--kioslave/trash/trashimpl.cpp962
-rw-r--r--kioslave/trash/trashimpl.h182
18 files changed, 0 insertions, 3810 deletions
diff --git a/kioslave/trash/CMakeLists.txt b/kioslave/trash/CMakeLists.txt
deleted file mode 100644
index 5dfd62cb2..000000000
--- a/kioslave/trash/CMakeLists.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-#################################################
-#
-# (C) 2010-2011 Serghei Amelian
-# serghei (DOT) amelian (AT) gmail.com
-#
-# Improvements and feedback are welcome
-#
-# This file is released under GPL >= 2
-#
-#################################################
-
-add_subdirectory( kfile-plugin )
-
-
-include_directories(
- ${CMAKE_CURRENT_BINARY_DIR}
- ${TDE_INCLUDE_DIR}
- ${TQT_INCLUDE_DIRS}
-)
-
-link_directories(
- ${TQT_LIBRARY_DIRS}
-)
-
-
-##### other data ################################
-
-install( FILES trash.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
-
-
-##### trashcommon (static) ######################
-
-set( target trashcommon )
-
-tde_add_library( ${target} STATIC_PIC AUTOMOC
- SOURCES trashimpl.cpp
-)
-
-
-##### kio_trash (module) ########################
-
-set( target kio_trash )
-
-tde_add_kpart( ${target} AUTOMOC
- SOURCES kio_trash.cpp
- LINK trashcommon-static kio-shared
- DESTINATION ${PLUGIN_INSTALL_DIR}
-)
-
-
-##### ktrash (executable) #######################
-
-set( target ktrash )
-
-tde_add_executable( ${target}
- SOURCES ktrash.cpp
- LINK kio-shared
- DESTINATION ${BIN_INSTALL_DIR}
-)
diff --git a/kioslave/trash/DESIGN b/kioslave/trash/DESIGN
deleted file mode 100644
index 63179da08..000000000
--- a/kioslave/trash/DESIGN
+++ /dev/null
@@ -1,53 +0,0 @@
-DESIGN
-======
-kio_trash implements the XDG trash standard currently at http://www.ramendik.ru/docs/trashspec.html
-
-In case race conditions between the various instances of kio_trash
-are a problem, trashimpl could be moved to a kded module, and
-kio_trash would use DCOP to talk to it. It's a bit hard to come up
-with use cases where the race conditions would matter though.
-
-BUGS
-====
-* Undo of "restore" isn't available. Need to get origPath by metadata I guess.
-
-TODO
-====
-* Clean up konq_popupmenu.cc for Type=Link URL=trash:/ :(
-* Also, provide metainfo for trash contents for that desktop link.
-=> maybe we need a new mimetype?
- Like application/x-trash-desktop, inheriting application/x-desktop.
- And a "trash.trashdesktop" filename or so (ouch, migration issues...)
-
-* Detect removeable media to avoid .Trash-foo on it. How?
-
-* Trashcan properties (properties for trash:/? hmm. Easier with separate dialog)
- - Maximum size for trash can (#18109 suggests a %, but a MB size is easier).
- This means to delete the oldest files from the trash automatically. #79553
-
-* Err, should we support renaming? :) Difficult to disable...
- In fact it's already not disabled in readonly directories (e.g. "/") -> todo
- (for F2 and kpropertiesdialog)
-
-* Deleting oldest files when size is bigger than a certain configurable amount (#79553)
-
-Bugs closed by kio_trash
-========================
-#79826 (3.3 only)
-#62848 (configurable trash location)
-#78116 (.directory)
-#18109 (general one)
-#17744 (restore)
-#76380 #56821 (trashing on same partition)
-
-Choice of URL scheme
-====================
-We use trash:/trashid-fileid[/relativepath]
-This gave problems with CopyJob::startRenameJob which exposed trashid-fileid
-to the user as a filename when dropping a file out of the trash.
-But this was fixed with the fileNameUsedForCopying=Name setting.
-
-A previous experiment was trash:/filename[/relativepath]?t=trashid&id=fileid
-but this gives problems with going Up (it first removes the query),
-with KDirLister (it wouldn't know when to remove the query, to find the URL
-of the parent directory).
diff --git a/kioslave/trash/Makefile.am b/kioslave/trash/Makefile.am
deleted file mode 100644
index 94b7ab519..000000000
--- a/kioslave/trash/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-INCLUDES = $(all_includes)
-METASOURCES = AUTO
-
-SUBDIRS = . kfile-plugin
-
-kde_module_LTLIBRARIES = kio_trash.la
-
-kio_trash_la_SOURCES = kio_trash.cpp
-kio_trash_la_LIBADD = libtrashcommon.la $(LIB_KIO)
-kio_trash_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined
-
-bin_PROGRAMS = ktrash
-ktrash_SOURCES = ktrash.cpp
-ktrash_LDADD = $(LIB_KIO)
-ktrash_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor
-
-kde_services_DATA = trash.protocol
-
-noinst_LTLIBRARIES = libtrashcommon.la
-libtrashcommon_la_SOURCES = trashimpl.cpp
-
-check_PROGRAMS = testtrash
-testtrash_SOURCES = testtrash.cpp
-testtrash_LDADD = libtrashcommon.la $(LIB_KIO)
-testtrash_LDFLAGS = $(all_libraries)
-
-TESTS = testtrash
-
-messages:
- $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/kio_trash.pot
-
diff --git a/kioslave/trash/kfile-plugin/CMakeLists.txt b/kioslave/trash/kfile-plugin/CMakeLists.txt
deleted file mode 100644
index 920144faa..000000000
--- a/kioslave/trash/kfile-plugin/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-#################################################
-#
-# (C) 2010-2011 Serghei Amelian
-# serghei (DOT) amelian (AT) gmail.com
-#
-# Improvements and feedback are welcome
-#
-# This file is released under GPL >= 2
-#
-#################################################
-
-include_directories(
- ${CMAKE_CURRENT_BINARY_DIR}
- ${TDE_INCLUDE_DIR}
- ${TQT_INCLUDE_DIRS}
-)
-
-link_directories(
- ${TQT_LIBRARY_DIRS}
-)
-
-
-##### other data ################################
-
-install( FILES
- kfile_trash.desktop kfile_trash_system.desktop
- DESTINATION ${SERVICES_INSTALL_DIR} )
-
-
-##### kfile_trash (module) ######################
-
-set( target kfile_trash )
-
-tde_add_kpart( ${target} AUTOMOC
- SOURCES kfile_trash.cpp
- LINK trashcommon-static kio-shared
- DESTINATION ${PLUGIN_INSTALL_DIR}
-)
diff --git a/kioslave/trash/kfile-plugin/Makefile.am b/kioslave/trash/kfile-plugin/Makefile.am
deleted file mode 100644
index 0668553a8..000000000
--- a/kioslave/trash/kfile-plugin/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-## Makefile.am for trash file meta info plugin
-
-AM_CPPFLAGS = $(all_includes)
-
-kde_module_LTLIBRARIES = kfile_trash.la
-
-kfile_trash_la_SOURCES = kfile_trash.cpp
-kfile_trash_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
-kfile_trash_la_LIBADD = ../libtrashcommon.la $(LIB_KIO)
-
-METASOURCES = AUTO
-
-services_DATA = kfile_trash.desktop kfile_trash_system.desktop
-servicesdir = $(kde_servicesdir)
diff --git a/kioslave/trash/kfile-plugin/RETURNED_ITEMS b/kioslave/trash/kfile-plugin/RETURNED_ITEMS
deleted file mode 100644
index 3e34c5b6d..000000000
--- a/kioslave/trash/kfile-plugin/RETURNED_ITEMS
+++ /dev/null
@@ -1,4 +0,0 @@
-kfile_trash
-===========
-QString OriginalPath
-DateTime DateOfDeletion
diff --git a/kioslave/trash/kfile-plugin/kfile_trash.cpp b/kioslave/trash/kfile-plugin/kfile_trash.cpp
deleted file mode 100644
index 182d9c40e..000000000
--- a/kioslave/trash/kfile-plugin/kfile_trash.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* This file is part of the KDE project
- * Copyright (C) 2004 David Faure <[email protected]>
- * Based on kfile_txt.cpp by Nadeem Hasan <[email protected]>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation version 2.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "kfile_trash.h"
-
-#include <kgenericfactory.h>
-#include <kdebug.h>
-
-#include <tqfile.h>
-#include <tqstringlist.h>
-#include <tqdatetime.h>
-
-typedef KGenericFactory<KTrashPlugin> TrashFactory;
-
-K_EXPORT_COMPONENT_FACTORY(kfile_trash, TrashFactory("kfile_trash"))
-
-KTrashPlugin::KTrashPlugin(TQObject *parent, const char *name,
- const TQStringList &args) : KFilePlugin(parent, name, args)
-{
- TDEGlobal::locale()->insertCatalogue( "kio_trash" );
-
- kdDebug(7034) << "Trash file meta info plugin\n";
-
- makeMimeTypeInfo("trash");
- makeMimeTypeInfo("system");
-
- (void)impl.init();
-}
-
-void KTrashPlugin::makeMimeTypeInfo(const TQString& mimeType)
-{
- KFileMimeTypeInfo* info = addMimeTypeInfo( mimeType );
-
- KFileMimeTypeInfo::GroupInfo* group =
- addGroupInfo(info, "General", i18n("General"));
-
- KFileMimeTypeInfo::ItemInfo* item;
- item = addItemInfo(group, "OriginalPath", i18n("Original Path"), TQVariant::String);
- item = addItemInfo(group, "DateOfDeletion", i18n("Date of Deletion"), TQVariant::DateTime);
-}
-
-bool KTrashPlugin::readInfo(KFileMetaInfo& info, uint)
-{
- KURL url = info.url();
-
- if ( url.protocol()=="system"
- && url.path().startsWith("/trash") )
- {
- TQString path = url.path();
- path.remove(0, 6);
- url.setProtocol("trash");
- url.setPath(path);
- }
-
- //kdDebug() << k_funcinfo << info.url() << endl;
- if ( url.protocol() != "trash" )
- return false;
-
- int trashId;
- TQString fileId;
- TQString relativePath;
- if ( !TrashImpl::parseURL( url, trashId, fileId, relativePath ) )
- return false;
-
- TrashImpl::TrashedFileInfo trashInfo;
- if ( !impl.infoForFile( trashId, fileId, trashInfo ) )
- return false;
-
- KFileMetaInfoGroup group = appendGroup(info, "General");
- appendItem(group, "OriginalPath", trashInfo.origPath);
- appendItem(group, "DateOfDeletion", trashInfo.deletionDate);
-
- return true;
-}
-
-#include "kfile_trash.moc"
diff --git a/kioslave/trash/kfile-plugin/kfile_trash.desktop b/kioslave/trash/kfile-plugin/kfile_trash.desktop
deleted file mode 100644
index 4b58a68dc..000000000
--- a/kioslave/trash/kfile-plugin/kfile_trash.desktop
+++ /dev/null
@@ -1,79 +0,0 @@
-[Desktop Entry]
-Type=Service
-Name=Trash File Info
-Name[af]=Asblik inligting
-Name[ar]=معلومات مفل المهملات
-Name[az]=Zibil Faylı Məlumatı
-Name[be]=Інфармацыя аб файле сметніцы
-Name[bg]=Информация за кошчето
-Name[bn]=আবর্জনা ফাইল তথ্য
-Name[br]=Titouroù diwar-benn ar pod-lastez
-Name[bs]=Smeće informacije o datoteci
-Name[ca]=Informació del fitxer paperera
-Name[cs]=Info o koši
-Name[csb]=Wëdowiédzô ò lopkù w kòszu
-Name[da]=Fil-info om affald
-Name[de]=Mülleimer-Information
-Name[el]=Πληροφορίες για τον Κάδο Απορριμμάτων
-Name[en_GB]=Wastebin File Info
-Name[eo]=Rubuja informo
-Name[es]=Información de la papelera
-Name[et]=Prügikasti failiinfo
-Name[eu]=Zakarontziaren infoa
-Name[fa]=اطلاعات پروندۀ زباله
-Name[fi]=Roskakorin tiedot
-Name[fr]=Info Fichier Corbeille
-Name[fy]=Jiskefet ynformaasje
-Name[gl]=Información do Lixo
-Name[he]=מידע אודות קובץ אשפה
-Name[hi]=रद्दी फ़ाइल जानकारी
-Name[hr]=Podaci o otpadu
-Name[hu]=Szemétkosár-jellemzők
-Name[is]=Upplýsingar um ruslaskrá
-Name[it]=Informazioni file del cestino
-Name[ja]=ごみ箱情報
-Name[ka]=ურნაში არსებული ფაილის შესახებ ცნობი
-Name[kk]=Өшірілген файл мәліметі
-Name[km]=ព័ត៌មាន​ឯកសារ​សំរាម
-Name[ko]=휴지통 파일 정보
-Name[lt]=Šiukšlių bylos informacija
-Name[lv]=Atkritumu faila informācija
-Name[mk]=Инфо. за датотека од Корпата
-Name[ms]=Maklumat Fail Sampah
-Name[mt]=Skart
-Name[nb]=Søppelfilinformasjon
-Name[nds]=Affalltünn-Informatschonen
-Name[ne]=रद्दीटोकरी फाइल सूचना
-Name[nl]=Prullenbakinformatie
-Name[nn]=Søppelfilinformasjon
-Name[pa]=ਰੱਦੀ ਫਾਇਲ ਜਾਣਕਾਰੀ
-Name[pl]=Informacja o pliku w koszu
-Name[pt]=Informações de Ficheiros no Lixo
-Name[pt_BR]=Informações sobre o Arquivo de Lixo
-Name[ro]=Informații fișier șters
-Name[ru]=Сведения о файле в корзине
-Name[rw]=Ibisobanuro byo Guta Idosiye
-Name[se]=Ruskalihttedieđut
-Name[sk]=Informácie o koši
-Name[sl]=Informacije o Smeteh
-Name[sr]=Информације о фајлу у смећу
-Name[sr@Latn]=Informacije o fajlu u smeću
-Name[sv]=Information om filer i papperskorgen
-Name[ta]=குப்பைத்தொட்டி கோப்பு தகவல்
-Name[te]=చెత్త బుట్ట దస్త్ర వివరాలు
-Name[tg]=Файли ахборотии ахлотдон
-Name[th]=ข้อมูลแฟ้มถังขยะ
-Name[tr]=Çöp Dosya Bilgisi
-Name[tt]=Taşlanğan Birem Turında
-Name[uk]=Інформація про файл у смітнику
-Name[uz]=Chiqindilar qutisi haqida maʼlumot
-Name[uz@cyrillic]=Чиқиндилар қутиси ҳақида маълумот
-Name[vi]=Thông tin về Tập tin trong Thùng rác
-Name[wa]=Informåcion sol fitchî batch
-Name[zh_CN]=回收站文件信息
-Name[zh_TW]=資源回收桶檔案資訊
-ServiceTypes=KFilePlugin
-X-TDE-Library=kfile_trash
-X-TDE-Protocol=trash
-PreferredGroups=General
-PreferredItems=OriginalPath,DateOfDeletion
diff --git a/kioslave/trash/kfile-plugin/kfile_trash.h b/kioslave/trash/kfile-plugin/kfile_trash.h
deleted file mode 100644
index 33f83e911..000000000
--- a/kioslave/trash/kfile-plugin/kfile_trash.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This file is part of the KDE project
- * Copyright (C) 2004 David Faure <[email protected]>
- * Based on kfile_txt.h by Nadeem Hasan <[email protected]>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License as published by the Free Software Foundation version 2.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef __KFILE_TRASH_H_
-#define __KFILE_TRASH_H_
-
-#include <kfilemetainfo.h>
-#include "../trashimpl.h"
-
-class TQStringList;
-
-class KTrashPlugin: public KFilePlugin
-{
- Q_OBJECT
-
-public:
- KTrashPlugin(TQObject *parent, const char *name, const TQStringList& args);
- virtual bool readInfo(KFileMetaInfo& info, uint what);
-
-private:
- void makeMimeTypeInfo(const TQString& mimeType);
- TrashImpl impl;
-};
-
-#endif
diff --git a/kioslave/trash/kfile-plugin/kfile_trash_system.desktop b/kioslave/trash/kfile-plugin/kfile_trash_system.desktop
deleted file mode 100644
index 3e3c8fe47..000000000
--- a/kioslave/trash/kfile-plugin/kfile_trash_system.desktop
+++ /dev/null
@@ -1,79 +0,0 @@
-[Desktop Entry]
-Type=Service
-Name=Trash File Info
-Name[af]=Asblik inligting
-Name[ar]=معلومات مفل المهملات
-Name[az]=Zibil Faylı Məlumatı
-Name[be]=Інфармацыя аб файле сметніцы
-Name[bg]=Информация за кошчето
-Name[bn]=আবর্জনা ফাইল তথ্য
-Name[br]=Titouroù diwar-benn ar pod-lastez
-Name[bs]=Smeće informacije o datoteci
-Name[ca]=Informació del fitxer paperera
-Name[cs]=Info o koši
-Name[csb]=Wëdowiédzô ò lopkù w kòszu
-Name[da]=Fil-info om affald
-Name[de]=Mülleimer-Information
-Name[el]=Πληροφορίες για τον Κάδο Απορριμμάτων
-Name[en_GB]=Wastebin File Info
-Name[eo]=Rubuja informo
-Name[es]=Información de la papelera
-Name[et]=Prügikasti failiinfo
-Name[eu]=Zakarontziaren infoa
-Name[fa]=اطلاعات پروندۀ زباله
-Name[fi]=Roskakorin tiedot
-Name[fr]=Info Fichier Corbeille
-Name[fy]=Jiskefet ynformaasje
-Name[gl]=Información do Lixo
-Name[he]=מידע אודות קובץ אשפה
-Name[hi]=रद्दी फ़ाइल जानकारी
-Name[hr]=Podaci o otpadu
-Name[hu]=Szemétkosár-jellemzők
-Name[is]=Upplýsingar um ruslaskrá
-Name[it]=Informazioni file del cestino
-Name[ja]=ごみ箱情報
-Name[ka]=ურნაში არსებული ფაილის შესახებ ცნობი
-Name[kk]=Өшірілген файл мәліметі
-Name[km]=ព័ត៌មាន​ឯកសារ​សំរាម
-Name[ko]=휴지통 파일 정보
-Name[lt]=Šiukšlių bylos informacija
-Name[lv]=Atkritumu faila informācija
-Name[mk]=Инфо. за датотека од Корпата
-Name[ms]=Maklumat Fail Sampah
-Name[mt]=Skart
-Name[nb]=Søppelfilinformasjon
-Name[nds]=Affalltünn-Informatschonen
-Name[ne]=रद्दीटोकरी फाइल सूचना
-Name[nl]=Prullenbakinformatie
-Name[nn]=Søppelfilinformasjon
-Name[pa]=ਰੱਦੀ ਫਾਇਲ ਜਾਣਕਾਰੀ
-Name[pl]=Informacja o pliku w koszu
-Name[pt]=Informações de Ficheiros no Lixo
-Name[pt_BR]=Informações sobre o Arquivo de Lixo
-Name[ro]=Informații fișier șters
-Name[ru]=Сведения о файле в корзине
-Name[rw]=Ibisobanuro byo Guta Idosiye
-Name[se]=Ruskalihttedieđut
-Name[sk]=Informácie o koši
-Name[sl]=Informacije o Smeteh
-Name[sr]=Информације о фајлу у смећу
-Name[sr@Latn]=Informacije o fajlu u smeću
-Name[sv]=Information om filer i papperskorgen
-Name[ta]=குப்பைத்தொட்டி கோப்பு தகவல்
-Name[te]=చెత్త బుట్ట దస్త్ర వివరాలు
-Name[tg]=Файли ахборотии ахлотдон
-Name[th]=ข้อมูลแฟ้มถังขยะ
-Name[tr]=Çöp Dosya Bilgisi
-Name[tt]=Taşlanğan Birem Turında
-Name[uk]=Інформація про файл у смітнику
-Name[uz]=Chiqindilar qutisi haqida maʼlumot
-Name[uz@cyrillic]=Чиқиндилар қутиси ҳақида маълумот
-Name[vi]=Thông tin về Tập tin trong Thùng rác
-Name[wa]=Informåcion sol fitchî batch
-Name[zh_CN]=回收站文件信息
-Name[zh_TW]=資源回收桶檔案資訊
-ServiceTypes=KFilePlugin
-X-TDE-Library=kfile_trash
-X-TDE-Protocol=system
-PreferredGroups=General
-PreferredItems=OriginalPath,DateOfDeletion
diff --git a/kioslave/trash/kio_trash.cpp b/kioslave/trash/kio_trash.cpp
deleted file mode 100644
index f77cbf9ab..000000000
--- a/kioslave/trash/kio_trash.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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_trash.h"
-#include <kio/job.h>
-
-#include <kapplication.h>
-#include <kdebug.h>
-#include <klocale.h>
-#include <klargefile.h>
-#include <kcmdlineargs.h>
-#include <kmimetype.h>
-#include <kprocess.h>
-
-#include <dcopclient.h>
-#include <tqdatastream.h>
-#include <tqtextstream.h>
-#include <tqfile.h>
-#include <tqeventloop.h>
-
-#include <time.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-static const KCmdLineOptions options[] =
-{
- { "+protocol", I18N_NOOP( "Protocol name" ), 0 },
- { "+pool", I18N_NOOP( "Socket name" ), 0 },
- { "+app", I18N_NOOP( "Socket name" ), 0 },
- KCmdLineLastOption
-};
-
-extern "C" {
- int KDE_EXPORT kdemain( int argc, char **argv )
- {
- //TDEInstance instance( "kio_trash" );
- // TDEApplication is necessary to use kio_file
- putenv(strdup("SESSION_MANAGER="));
- TDEApplication::disableAutoDcopRegistration();
- TDECmdLineArgs::init(argc, argv, "kio_trash", 0, 0, 0, 0);
- TDECmdLineArgs::addCmdLineOptions( options );
- TDEApplication app( false, false );
-
- TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
- TrashProtocol slave( args->arg(0), args->arg(1), args->arg(2) );
- slave.dispatchLoop();
- return 0;
- }
-}
-
-#define INIT_IMPL \
- if ( !impl.init() ) { \
- error( impl.lastErrorCode(), impl.lastErrorMessage() ); \
- return; \
- }
-
-TrashProtocol::TrashProtocol( const TQCString& protocol, const TQCString &pool, const TQCString &app)
- : SlaveBase(protocol, pool, app )
-{
- struct passwd *user = getpwuid( getuid() );
- if ( user )
- m_userName = TQString::fromLatin1(user->pw_name);
- struct group *grp = getgrgid( getgid() );
- if ( grp )
- m_groupName = TQString::fromLatin1(grp->gr_name);
-}
-
-TrashProtocol::~TrashProtocol()
-{
-}
-
-void TrashProtocol::restore( const KURL& trashURL )
-{
- int trashId;
- TQString fileId, relativePath;
- bool ok = TrashImpl::parseURL( trashURL, trashId, fileId, relativePath );
- if ( !ok ) {
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( trashURL.prettyURL() ) );
- return;
- }
- TrashedFileInfo info;
- ok = impl.infoForFile( trashId, fileId, info );
- if ( !ok ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- return;
- }
- KURL dest;
- dest.setPath( info.origPath );
- if ( !relativePath.isEmpty() )
- dest.addPath( relativePath );
-
- // Check that the destination directory exists, to improve the error code in case it doesn't.
- const TQString destDir = dest.directory();
- KDE_struct_stat buff;
- if ( KDE_lstat( TQFile::encodeName( destDir ), &buff ) == -1 ) {
- error( TDEIO::ERR_SLAVE_DEFINED,
- i18n( "The directory %1 does not exist anymore, so it is not possible to restore this item to its original location. "
- "You can either recreate that directory and use the restore operation again, or drag the item anywhere else to restore it." ).arg( destDir ) );
- return;
- }
-
- copyOrMove( trashURL, dest, false /*overwrite*/, Move );
-}
-
-void TrashProtocol::rename( const KURL &oldURL, const KURL &newURL, bool overwrite )
-{
- INIT_IMPL;
-
- kdDebug()<<"TrashProtocol::rename(): old="<<oldURL<<" new="<<newURL<<" overwrite=" << overwrite<<endl;
-
- if ( oldURL.protocol() == "trash" && newURL.protocol() == "trash" ) {
- error( TDEIO::ERR_CANNOT_RENAME, oldURL.prettyURL() );
- return;
- }
-
- copyOrMove( oldURL, newURL, overwrite, Move );
-}
-
-void TrashProtocol::copy( const KURL &src, const KURL &dest, int /*permissions*/, bool overwrite )
-{
- INIT_IMPL;
-
- kdDebug()<<"TrashProtocol::copy(): " << src << " " << dest << endl;
-
- if ( src.protocol() == "trash" && dest.protocol() == "trash" ) {
- error( TDEIO::ERR_UNSUPPORTED_ACTION, i18n( "This file is already in the trash bin." ) );
- return;
- }
-
- copyOrMove( src, dest, overwrite, Copy );
-}
-
-void TrashProtocol::copyOrMove( const KURL &src, const KURL &dest, bool overwrite, CopyOrMove action )
-{
- if ( src.protocol() == "trash" && dest.isLocalFile() ) {
- // Extracting (e.g. via dnd). Ignore original location stored in info file.
- int trashId;
- TQString fileId, relativePath;
- bool ok = TrashImpl::parseURL( src, trashId, fileId, relativePath );
- if ( !ok ) {
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( src.prettyURL() ) );
- return;
- }
- const TQString destPath = dest.path();
- if ( TQFile::exists( destPath ) ) {
- if ( overwrite ) {
- ok = TQFile::remove( destPath );
- Q_ASSERT( ok ); // ### TODO
- } else {
- error( TDEIO::ERR_FILE_ALREADY_EXIST, destPath );
- return;
- }
- }
-
- if ( action == Move ) {
- kdDebug() << "calling moveFromTrash(" << destPath << " " << trashId << " " << fileId << ")" << endl;
- ok = impl.moveFromTrash( destPath, trashId, fileId, relativePath );
- } else { // Copy
- kdDebug() << "calling copyFromTrash(" << destPath << " " << trashId << " " << fileId << ")" << endl;
- ok = impl.copyFromTrash( destPath, trashId, fileId, relativePath );
- }
- if ( !ok ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- } else {
- if ( action == Move && relativePath.isEmpty() )
- (void)impl.deleteInfo( trashId, fileId );
- finished();
- }
- return;
- } else if ( src.isLocalFile() && dest.protocol() == "trash" ) {
- TQString dir = dest.directory();
- //kdDebug() << "trashing a file to " << dir << endl;
- // Trashing a file
- // We detect the case where this isn't normal trashing, but
- // e.g. if kwrite tries to save (moving tempfile over destination)
- if ( dir.length() <= 1 && src.fileName() == dest.fileName() ) // new toplevel entry
- {
- const TQString srcPath = src.path();
- // In theory we should use TrashImpl::parseURL to give the right filename to createInfo,
- // in case the trash URL didn't contain the same filename as srcPath.
- // But this can only happen with copyAs/moveAs, not available in the GUI
- // for the trash (New/... or Rename from iconview/listview).
- int trashId;
- TQString fileId;
- if ( !impl.createInfo( srcPath, trashId, fileId ) ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- } else {
- bool ok;
- if ( action == Move ) {
- kdDebug() << "calling moveToTrash(" << srcPath << " " << trashId << " " << fileId << ")" << endl;
- ok = impl.moveToTrash( srcPath, trashId, fileId );
- } else { // Copy
- kdDebug() << "calling copyToTrash(" << srcPath << " " << trashId << " " << fileId << ")" << endl;
- ok = impl.copyToTrash( srcPath, trashId, fileId );
- }
- if ( !ok ) {
- (void)impl.deleteInfo( trashId, fileId );
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- } else {
- // Inform caller of the final URL. Used by konq_undo.
- const KURL url = impl.makeURL( trashId, fileId, TQString::null );
- setMetaData( "trashURL-" + srcPath, url.url() );
- finished();
- }
- }
- return;
- } else {
- kdDebug() << "returning TDEIO::ERR_ACCESS_DENIED, it's not allowed to add a file to an existing trash directory" << endl;
- // It's not allowed to add a file to an existing trash directory.
- error( TDEIO::ERR_ACCESS_DENIED, dest.prettyURL() );
- return;
- }
- } else
- error( TDEIO::ERR_UNSUPPORTED_ACTION, "should never happen" );
-}
-
-static void addAtom(TDEIO::UDSEntry& entry, unsigned int ID, long long l, const TQString& s = TQString::null)
-{
- TDEIO::UDSAtom atom;
- atom.m_uds = ID;
- atom.m_long = l;
- atom.m_str = s;
- entry.append(atom);
-}
-
-void TrashProtocol::createTopLevelDirEntry(TDEIO::UDSEntry& entry)
-{
- entry.clear();
- addAtom(entry, TDEIO::UDS_NAME, 0, ".");
- addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR);
- addAtom(entry, TDEIO::UDS_ACCESS, 0700);
- addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, "inode/directory");
- addAtom(entry, TDEIO::UDS_USER, 0, m_userName);
- addAtom(entry, TDEIO::UDS_GROUP, 0, m_groupName);
-}
-
-void TrashProtocol::stat(const KURL& url)
-{
- INIT_IMPL;
- const TQString path = url.path();
- if( path.isEmpty() || path == "/" ) {
- // The root is "virtual" - it's not a single physical directory
- TDEIO::UDSEntry entry;
- createTopLevelDirEntry( entry );
- statEntry( entry );
- finished();
- } else {
- int trashId;
- TQString fileId, relativePath;
-
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
-
- if ( !ok ) {
- // ######## do we still need this?
- kdDebug() << k_funcinfo << url << " looks fishy, returning does-not-exist" << endl;
- // A URL like trash:/file simply means that CopyJob is trying to see if
- // the destination exists already (it made up the URL by itself).
- error( TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
- //error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( url.prettyURL() ) );
- return;
- }
-
- const TQString filePath = impl.physicalPath( trashId, fileId, relativePath );
- if ( filePath.isEmpty() ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- return;
- }
-
- TQString fileName = filePath.section('/', -1, -1, TQString::SectionSkipEmpty);
-
- TQString fileURL = TQString::null;
- if ( url.path().length() > 1 ) {
- fileURL = url.url();
- }
-
- TDEIO::UDSEntry entry;
- TrashedFileInfo info;
- ok = impl.infoForFile( trashId, fileId, info );
- if ( ok )
- ok = createUDSEntry( filePath, fileName, fileURL, entry, info );
-
- if ( !ok ) {
- error( TDEIO::ERR_COULD_NOT_STAT, url.prettyURL() );
- }
-
- statEntry( entry );
- finished();
- }
-}
-
-void TrashProtocol::del( const KURL &url, bool /*isfile*/ )
-{
- int trashId;
- TQString fileId, relativePath;
-
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- if ( !ok ) {
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( url.prettyURL() ) );
- return;
- }
-
- ok = relativePath.isEmpty();
- if ( !ok ) {
- error( TDEIO::ERR_ACCESS_DENIED, url.prettyURL() );
- return;
- }
-
- ok = impl.del(trashId, fileId);
- if ( !ok ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- return;
- }
-
- finished();
-}
-
-void TrashProtocol::listDir(const KURL& url)
-{
- INIT_IMPL;
- kdDebug() << "listdir: " << url << endl;
- if ( url.path().length() <= 1 ) {
- listRoot();
- return;
- }
- int trashId;
- TQString fileId;
- TQString relativePath;
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- if ( !ok ) {
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( url.prettyURL() ) );
- return;
- }
- //was: const TQString physicalPath = impl.physicalPath( trashId, fileId, relativePath );
-
- // Get info for deleted directory - the date of deletion and orig path will be used
- // for all the items in it, and we need the physicalPath.
- TrashedFileInfo info;
- ok = impl.infoForFile( trashId, fileId, info );
- if ( !ok || info.physicalPath.isEmpty() ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- return;
- }
- if ( !relativePath.isEmpty() ) {
- info.physicalPath += "/";
- info.physicalPath += relativePath;
- }
-
- // List subdir. Can't use kio_file here since we provide our own info...
- kdDebug() << k_funcinfo << "listing " << info.physicalPath << endl;
- TQStrList entryNames = impl.listDir( info.physicalPath );
- totalSize( entryNames.count() );
- TDEIO::UDSEntry entry;
- TQStrListIterator entryIt( entryNames );
- for (; entryIt.current(); ++entryIt) {
- TQString fileName = TQFile::decodeName( entryIt.current() );
- if ( fileName == ".." )
- continue;
- const TQString filePath = info.physicalPath + "/" + fileName;
- // shouldn't be necessary
- //const TQString url = TrashImpl::makeURL( trashId, fileId, relativePath + "/" + fileName );
- entry.clear();
- TrashedFileInfo infoForItem( info );
- infoForItem.origPath += '/';
- infoForItem.origPath += fileName;
- if ( ok && createUDSEntry( filePath, fileName, TQString::null /*url*/, entry, infoForItem ) ) {
- listEntry( entry, false );
- }
- }
- entry.clear();
- listEntry( entry, true );
- finished();
-}
-
-bool TrashProtocol::createUDSEntry( const TQString& physicalPath, const TQString& fileName, const TQString& url, TDEIO::UDSEntry& entry, const TrashedFileInfo& info )
-{
- TQCString physicalPath_c = TQFile::encodeName( physicalPath );
- KDE_struct_stat buff;
- if ( KDE_lstat( physicalPath_c, &buff ) == -1 ) {
- kdWarning() << "couldn't stat " << physicalPath << endl;
- return false;
- }
- if (S_ISLNK(buff.st_mode)) {
- char buffer2[ 1000 ];
- int n = readlink( physicalPath_c, buffer2, 1000 );
- if ( n != -1 ) {
- buffer2[ n ] = 0;
- }
-
- addAtom( entry, TDEIO::UDS_LINK_DEST, 0, TQFile::decodeName( buffer2 ) );
- // Follow symlink
- // That makes sense in kio_file, but not in the trash, especially for the size
- // #136876
-#if 0
- if ( KDE_stat( physicalPath_c, &buff ) == -1 ) {
- // It is a link pointing to nowhere
- buff.st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
- buff.st_mtime = 0;
- buff.st_atime = 0;
- buff.st_size = 0;
- }
-#endif
- }
- mode_t type = buff.st_mode & S_IFMT; // extract file type
- mode_t access = buff.st_mode & 07777; // extract permissions
- access &= 07555; // make it readonly, since it's in the trashcan
- addAtom( entry, TDEIO::UDS_NAME, 0, fileName );
- addAtom( entry, TDEIO::UDS_FILE_TYPE, type );
- if ( !url.isEmpty() )
- addAtom( entry, TDEIO::UDS_URL, 0, url );
-
- KMimeType::Ptr mt = KMimeType::findByPath( physicalPath, buff.st_mode );
- addAtom( entry, TDEIO::UDS_MIME_TYPE, 0, mt->name() );
- addAtom( entry, TDEIO::UDS_ACCESS, access );
- addAtom( entry, TDEIO::UDS_SIZE, buff.st_size );
- addAtom( entry, TDEIO::UDS_USER, 0, m_userName ); // assumption
- addAtom( entry, TDEIO::UDS_GROUP, 0, m_groupName ); // assumption
- addAtom( entry, TDEIO::UDS_MODIFICATION_TIME, buff.st_mtime );
- addAtom( entry, TDEIO::UDS_ACCESS_TIME, buff.st_atime ); // ## or use it for deletion time?
- addAtom( entry, TDEIO::UDS_EXTRA, 0, info.origPath );
- addAtom( entry, TDEIO::UDS_EXTRA, 0, info.deletionDate.toString( Qt::ISODate ) );
- return true;
-}
-
-void TrashProtocol::listRoot()
-{
- INIT_IMPL;
- const TrashedFileInfoList lst = impl.list();
- totalSize( lst.count() );
- TDEIO::UDSEntry entry;
- createTopLevelDirEntry( entry );
- listEntry( entry, false );
- for ( TrashedFileInfoList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
- const KURL url = TrashImpl::makeURL( (*it).trashId, (*it).fileId, TQString::null );
- KURL origURL;
- origURL.setPath( (*it).origPath );
- entry.clear();
- if ( createUDSEntry( (*it).physicalPath, origURL.fileName(), url.url(), entry, *it ) )
- listEntry( entry, false );
- }
- entry.clear();
- listEntry( entry, true );
- finished();
-}
-
-void TrashProtocol::special( const TQByteArray & data )
-{
- INIT_IMPL;
- TQDataStream stream( data, IO_ReadOnly );
- int cmd;
- stream >> cmd;
-
- switch (cmd) {
- case 1:
- if ( impl.emptyTrash() )
- finished();
- else
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- break;
- case 2:
- impl.migrateOldTrash();
- finished();
- break;
- case 3:
- {
- KURL url;
- stream >> url;
- restore( url );
- break;
- }
- default:
- kdWarning(7116) << "Unknown command in special(): " << cmd << endl;
- error( TDEIO::ERR_UNSUPPORTED_ACTION, TQString::number(cmd) );
- break;
- }
-}
-
-void TrashProtocol::put( const KURL& url, int /*permissions*/, bool /*overwrite*/, bool /*resume*/ )
-{
- INIT_IMPL;
- kdDebug() << "put: " << url << endl;
- // create deleted file. We need to get the mtime and original location from metadata...
- // Maybe we can find the info file for url.fileName(), in case ::rename() was called first, and failed...
- error( TDEIO::ERR_ACCESS_DENIED, url.prettyURL() );
-}
-
-void TrashProtocol::get( const KURL& url )
-{
- INIT_IMPL;
- kdDebug() << "get() : " << url << endl;
- if ( !url.isValid() ) {
- kdDebug() << kdBacktrace() << endl;
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( url.url() ) );
- return;
- }
- if ( url.path().length() <= 1 ) {
- error( TDEIO::ERR_IS_DIRECTORY, url.prettyURL() );
- return;
- }
- int trashId;
- TQString fileId;
- TQString relativePath;
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- if ( !ok ) {
- error( TDEIO::ERR_SLAVE_DEFINED, i18n( "Malformed URL %1" ).arg( url.prettyURL() ) );
- return;
- }
- const TQString physicalPath = impl.physicalPath( trashId, fileId, relativePath );
- if ( physicalPath.isEmpty() ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- return;
- }
-
- // Usually we run jobs in TrashImpl (for e.g. future kdedmodule)
- // But for this one we wouldn't use DCOP for every bit of data...
- KURL fileURL;
- fileURL.setPath( physicalPath );
- TDEIO::Job* job = TDEIO::get( fileURL );
- connect( job, TQT_SIGNAL( data( TDEIO::Job*, const TQByteArray& ) ),
- this, TQT_SLOT( slotData( TDEIO::Job*, const TQByteArray& ) ) );
- connect( job, TQT_SIGNAL( mimetype( TDEIO::Job*, const TQString& ) ),
- this, TQT_SLOT( slotMimetype( TDEIO::Job*, const TQString& ) ) );
- connect( job, TQT_SIGNAL( result(TDEIO::Job *) ),
- this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
- tqApp->eventLoop()->enterLoop();
-}
-
-void TrashProtocol::slotData( TDEIO::Job*, const TQByteArray&arr )
-{
- data( arr );
-}
-
-void TrashProtocol::slotMimetype( TDEIO::Job*, const TQString& mt )
-{
- mimeType( mt );
-}
-
-void TrashProtocol::jobFinished( TDEIO::Job* job )
-{
- if ( job->error() )
- error( job->error(), job->errorText() );
- else
- finished();
- tqApp->eventLoop()->exitLoop();
-}
-
-#if 0
-void TrashProtocol::mkdir( const KURL& url, int /*permissions*/ )
-{
- INIT_IMPL;
- // create info about deleted dir
- // ############ Problem: we don't know the original path.
- // Let's try to avoid this case (we should get to copy() instead, for local files)
- kdDebug() << "mkdir: " << url << endl;
- TQString dir = url.directory();
-
- if ( dir.length() <= 1 ) // new toplevel entry
- {
- // ## we should use TrashImpl::parseURL to give the right filename to createInfo
- int trashId;
- TQString fileId;
- if ( !impl.createInfo( url.path(), trashId, fileId ) ) {
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- } else {
- if ( !impl.mkdir( trashId, fileId, permissions ) ) {
- (void)impl.deleteInfo( trashId, fileId );
- error( impl.lastErrorCode(), impl.lastErrorMessage() );
- } else
- finished();
- }
- } else {
- // Well it's not allowed to add a directory to an existing deleted directory.
- error( TDEIO::ERR_ACCESS_DENIED, url.prettyURL() );
- }
-}
-#endif
-
-#include "kio_trash.moc"
diff --git a/kioslave/trash/kio_trash.h b/kioslave/trash/kio_trash.h
deleted file mode 100644
index 6f94512d7..000000000
--- a/kioslave/trash/kio_trash.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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_TRASH_H
-#define KIO_TRASH_H
-
-#include <kio/slavebase.h>
-#include "trashimpl.h"
-namespace TDEIO { class Job; }
-
-typedef TrashImpl::TrashedFileInfo TrashedFileInfo;
-typedef TrashImpl::TrashedFileInfoList TrashedFileInfoList;
-
-class TrashProtocol : public TQObject, public TDEIO::SlaveBase
-{
- Q_OBJECT
-public:
- TrashProtocol( const TQCString& protocol, const TQCString &pool, const TQCString &app);
- virtual ~TrashProtocol();
- virtual void stat(const KURL& url);
- virtual void listDir(const KURL& url);
- virtual void get( const KURL& url );
- virtual void put( const KURL& url, int , bool overwrite, bool );
- virtual void rename( const KURL &, const KURL &, bool );
- virtual void copy( const KURL &src, const KURL &dest, int permissions, bool overwrite );
- // TODO (maybe) chmod( const KURL& url, int permissions );
- virtual void del( const KURL &url, bool isfile );
- /**
- * Special actions: (first int in the byte array)
- * 1 : empty trash
- * 2 : migrate old (pre-kde-3.4) trash contents
- * 3 : restore a file to its original location. Args: KURL trashURL.
- */
- virtual void special( const TQByteArray & data );
-
-private slots:
- void slotData( TDEIO::Job*, const TQByteArray& );
- void slotMimetype( TDEIO::Job*, const TQString& );
- void jobFinished( TDEIO::Job* job );
-
-private:
- typedef enum CopyOrMove { Copy, Move };
- void copyOrMove( const KURL& src, const KURL& dest, bool overwrite, CopyOrMove action );
- void createTopLevelDirEntry(TDEIO::UDSEntry& entry);
- bool createUDSEntry( const TQString& physicalPath, const TQString& fileName, const TQString& url,
- TDEIO::UDSEntry& entry, const TrashedFileInfo& info );
- void listRoot();
- void restore( const KURL& trashURL );
-
- TrashImpl impl;
- TQString m_userName;
- TQString m_groupName;
-};
-
-#endif
diff --git a/kioslave/trash/ktrash.cpp b/kioslave/trash/ktrash.cpp
deleted file mode 100644
index b05cac249..000000000
--- a/kioslave/trash/ktrash.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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 <kapplication.h>
-#include <kio/netaccess.h>
-#include <kio/job.h>
-#include <kcmdlineargs.h>
-#include <klocale.h>
-#include <kdirnotify_stub.h>
-#include <kdebug.h>
-
-static KCmdLineOptions options[] =
-{
- { "empty", I18N_NOOP( "Empty the contents of the trash" ), 0 },
- //{ "migrate", I18N_NOOP( "Migrate contents of old trash" ), 0 },
- { "restore <file>", I18N_NOOP( "Restore a trashed file to its original location" ), 0 },
- // This hack is for the servicemenu on trash.desktop which uses Exec=ktrash -empty. %f is implied...
- { "+[ignored]", I18N_NOOP( "Ignored" ), 0 },
- KCmdLineLastOption
-};
-
-int main(int argc, char *argv[])
-{
- TDEApplication::disableAutoDcopRegistration();
- TDECmdLineArgs::init( argc, argv, "ktrash",
- I18N_NOOP( "ktrash" ),
- I18N_NOOP( "Helper program to handle the TDE trash can\n"
- "Note: to move files to the trash, do not use ktrash, but \"kfmclient move 'url' trash:/\"" ),
- TDE_VERSION_STRING );
- TDECmdLineArgs::addCmdLineOptions( options );
- TDEApplication app;
-
- TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
- if ( args->isSet( "empty" ) ) {
- // We use a kio job instead of linking to TrashImpl, for a smaller binary
- // (and the possibility of a central service at some point)
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)1;
- TDEIO::Job* job = TDEIO::special( "trash:/", packedArgs );
- (void)TDEIO::NetAccess::synchronousRun( job, 0 );
-
- // Update konq windows opened on trash:/
- KDirNotify_stub allDirNotify("*", "KDirNotify*");
- allDirNotify.FilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
- return 0;
- }
-
-#if 0
- // This is only for testing. KDesktop handles it automatically.
- if ( args->isSet( "migrate" ) ) {
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)2;
- TDEIO::Job* job = TDEIO::special( "trash:/", packedArgs );
- (void)TDEIO::NetAccess::synchronousRun( job, 0 );
- return 0;
- }
-#endif
-
- TQCString restoreArg = args->getOption( "restore" );
- if ( !restoreArg.isEmpty() ) {
-
- if (restoreArg.find("system:/trash")==0) {
- restoreArg.remove(0, 13);
- restoreArg.prepend("trash:");
- }
-
- KURL trashURL( restoreArg );
- if ( !trashURL.isValid() || trashURL.protocol() != "trash" ) {
- kdError() << "Invalid URL for restoring a trashed file:" << trashURL << endl;
- return 1;
- }
-
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)3 << trashURL;
- TDEIO::Job* job = TDEIO::special( trashURL, packedArgs );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- if ( !ok )
- kdError() << TDEIO::NetAccess::lastErrorString() << endl;
- return 0;
- }
-
- return 0;
-}
diff --git a/kioslave/trash/testtrash.cpp b/kioslave/trash/testtrash.cpp
deleted file mode 100644
index e3d06a6d2..000000000
--- a/kioslave/trash/testtrash.cpp
+++ /dev/null
@@ -1,1198 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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.
-*/
-
-// Get those asserts to work
-#undef NDEBUG
-#undef NO_DEBUG
-
-#include "kio_trash.h"
-#include "testtrash.h"
-
-#include <config.h>
-
-#include <kurl.h>
-#include <klocale.h>
-#include <kapplication.h>
-#include <kio/netaccess.h>
-#include <kio/job.h>
-#include <kdebug.h>
-#include <kcmdlineargs.h>
-
-#include <tqdir.h>
-#include <tqfileinfo.h>
-#include <tqvaluevector.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <assert.h>
-#include <kfileitem.h>
-#include <kstandarddirs.h>
-
-static bool check(const TQString& txt, TQString a, TQString b)
-{
- if (a.isEmpty())
- a = TQString::null;
- if (b.isEmpty())
- b = TQString::null;
- if (a == b) {
- kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
- }
- else {
- kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl;
- exit(1);
- }
- return true;
-}
-
-// There are two ways to test encoding things:
-// * with utf8 filenames
-// * with latin1 filenames
-//
-//#define UTF8TEST 1
-
-int main(int argc, char *argv[])
-{
- // Ensure a known TQFile::encodeName behavior for trashUtf8FileFromHome
- // However this assume your $HOME doesn't use characters from other locales...
- setenv( "LC_ALL", "en_GB.ISO-8859-1", 1 );
-#ifdef UTF8TEST
- setenv( "TDE_UTF8_FILENAMES", "true", 1 );
-#else
- unsetenv( "TDE_UTF8_FILENAMES" );
-#endif
-
- // Use another directory than the real one, just to keep things clean
- setenv( "XDG_DATA_HOME", TQFile::encodeName( TQDir::homeDirPath() + "/.local-testtrash" ), true );
- setenv( "TDE_FORK_SLAVES", "yes", true );
-
- TDEApplication::disableAutoDcopRegistration();
- TDECmdLineArgs::init(argc,argv,"testtrash", 0, 0, 0, 0);
- TDEApplication app;
-
- TestTrash test;
- test.setup();
- test.runAll();
- kdDebug() << "All tests OK." << endl;
- return 0; // success. The exit(1) in check() is what happens in case of failure.
-}
-
-TQString TestTrash::homeTmpDir() const
-{
- return TQDir::homeDirPath() + "/.trinity/testtrash/";
-}
-
-TQString TestTrash::readOnlyDirPath() const
-{
- return homeTmpDir() + TQString( "readonly" );
-}
-
-TQString TestTrash::otherTmpDir() const
-{
- // This one needs to be on another partition
- return "/tmp/testtrash/";
-}
-
-TQString TestTrash::utf8FileName() const
-{
- return TQString( "test" ) + TQChar( 0x2153 ); // "1/3" character, not part of latin1
-}
-
-TQString TestTrash::umlautFileName() const
-{
- return TQString( "umlaut" ) + TQChar( 0xEB );
-}
-
-static void removeFile( const TQString& trashDir, const TQString& fileName )
-{
- TQDir dir;
- dir.remove( trashDir + fileName );
- assert( !TQDir( trashDir + fileName ).exists() );
-}
-
-static void removeDir( const TQString& trashDir, const TQString& dirName )
-{
- TQDir dir;
- dir.rmdir( trashDir + dirName );
- assert( !TQDir( trashDir + dirName ).exists() );
-}
-
-void TestTrash::setup()
-{
- m_trashDir = TDEGlobal::dirs()->localxdgdatadir() + "Trash";
- kdDebug() << "setup: using trash directory " << m_trashDir << endl;
-
- // Look for another writable partition than $HOME (not mandatory)
- TrashImpl impl;
- impl.init();
-
- TrashImpl::TrashDirMap trashDirs = impl.trashDirectories();
- TrashImpl::TrashDirMap topDirs = impl.topDirectories();
- bool foundTrashDir = false;
- m_otherPartitionId = 0;
- m_tmpIsWritablePartition = false;
- m_tmpTrashId = -1;
- TQValueVector<int> writableTopDirs;
- for ( TrashImpl::TrashDirMap::ConstIterator it = trashDirs.begin(); it != trashDirs.end() ; ++it ) {
- if ( it.key() == 0 ) {
- assert( it.data() == m_trashDir );
- assert( topDirs.find( 0 ) == topDirs.end() );
- foundTrashDir = true;
- } else {
- assert( topDirs.find( it.key() ) != topDirs.end() );
- const TQString topdir = topDirs[it.key()];
- if ( TQFileInfo( topdir ).isWritable() ) {
- writableTopDirs.append( it.key() );
- if ( topdir == "/tmp/" ) {
- m_tmpIsWritablePartition = true;
- m_tmpTrashId = it.key();
- kdDebug() << "/tmp is on its own partition (trashid=" << m_tmpTrashId << "), some tests will be skipped" << endl;
- removeFile( it.data(), "/info/fileFromOther.trashinfo" );
- removeFile( it.data(), "/files/fileFromOther" );
- removeFile( it.data(), "/info/symlinkFromOther.trashinfo" );
- removeFile( it.data(), "/files/symlinkFromOther" );
- removeFile( it.data(), "/info/trashDirFromOther.trashinfo" );
- removeFile( it.data(), "/files/trashDirFromOther/testfile" );
- removeDir( it.data(), "/files/trashDirFromOther" );
- }
- }
- }
- }
- for ( TQValueVector<int>::const_iterator it = writableTopDirs.begin(); it != writableTopDirs.end(); ++it ) {
- const TQString topdir = topDirs[ *it ];
- const TQString trashdir = trashDirs[ *it ];
- assert( !topdir.isEmpty() );
- assert( !trashDirs.isEmpty() );
- if ( topdir != "/tmp/" || // we'd prefer not to use /tmp here, to separate the tests
- ( writableTopDirs.count() > 1 ) ) // but well, if we have no choice, take it
- {
- m_otherPartitionTopDir = topdir;
- m_otherPartitionTrashDir = trashdir;
- m_otherPartitionId = *it;
- kdDebug() << "OK, found another writable partition: topDir=" << m_otherPartitionTopDir
- << " trashDir=" << m_otherPartitionTrashDir << " id=" << m_otherPartitionId << endl;
- break;
- }
- }
- // Check that m_trashDir got listed
- assert( foundTrashDir );
- if ( m_otherPartitionTrashDir.isEmpty() )
- kdWarning() << "No writable partition other than $HOME found, some tests will be skipped" << endl;
-
- // Start with a clean base dir
- if ( TQFileInfo( homeTmpDir() ).exists() ) {
- bool ok = TDEIO::NetAccess::del( homeTmpDir(), 0 );
- if ( !ok )
- kdFatal() << "Couldn't delete " << homeTmpDir() << endl;
- }
- if ( TQFileInfo( otherTmpDir() ).exists() ) {
- bool ok = TDEIO::NetAccess::del( otherTmpDir(), 0 );
- if ( !ok )
- kdFatal() << "Couldn't delete " << otherTmpDir() << endl;
- }
- TQDir dir; // TT: why not a static method?
- bool ok = dir.mkdir( homeTmpDir() );
- if ( !ok )
- kdFatal() << "Couldn't create " << homeTmpDir() << endl;
- ok = dir.mkdir( otherTmpDir() );
- if ( !ok )
- kdFatal() << "Couldn't create " << otherTmpDir() << endl;
- cleanTrash();
-}
-
-
-void TestTrash::cleanTrash()
-{
- kdDebug() << k_funcinfo << endl;
- // Start with a relatively clean trash too
- removeFile( m_trashDir, "/info/fileFromHome.trashinfo" );
- removeFile( m_trashDir, "/files/fileFromHome" );
- removeFile( m_trashDir, "/info/fileFromHome_1.trashinfo" );
- removeFile( m_trashDir, "/files/fileFromHome_1" );
- removeFile( m_trashDir, "/info/file%2f.trashinfo" );
- removeFile( m_trashDir, "/files/file%2f" );
- removeFile( m_trashDir, "/info/" + utf8FileName() + ".trashinfo" );
- removeFile( m_trashDir, "/files/" + utf8FileName() );
- removeFile( m_trashDir, "/info/" + umlautFileName() + ".trashinfo" );
- removeFile( m_trashDir, "/files/" + umlautFileName() );
- removeFile( m_trashDir, "/info/fileFromOther.trashinfo" );
- removeFile( m_trashDir, "/files/fileFromOther" );
- removeFile( m_trashDir, "/info/symlinkFromHome.trashinfo" );
- removeFile( m_trashDir, "/files/symlinkFromHome" );
- removeFile( m_trashDir, "/info/symlinkFromOther.trashinfo" );
- removeFile( m_trashDir, "/files/symlinkFromOther" );
- removeFile( m_trashDir, "/info/brokenSymlinkFromHome.trashinfo" );
- removeFile( m_trashDir, "/files/brokenSymlinkFromHome" );
- removeFile( m_trashDir, "/info/trashDirFromHome.trashinfo" );
- removeFile( m_trashDir, "/files/trashDirFromHome/testfile" );
- removeFile( m_trashDir, "/info/readonly.trashinfo" );
- removeDir( m_trashDir, "/files/trashDirFromHome" );
- removeFile( m_trashDir, "/info/trashDirFromHome_1.trashinfo" );
- removeFile( m_trashDir, "/files/trashDirFromHome_1/testfile" );
- removeDir( m_trashDir, "/files/trashDirFromHome_1" );
- removeFile( m_trashDir, "/info/trashDirFromOther.trashinfo" );
- removeFile( m_trashDir, "/files/trashDirFromOther/testfile" );
- removeDir( m_trashDir, "/files/trashDirFromOther" );
- TDEIO::NetAccess::del( m_trashDir + "/files/readonly", 0 );
- // for trashDirectoryOwnedByRoot
- TDEIO::NetAccess::del( m_trashDir + "/files/cups", 0 );
- TDEIO::NetAccess::del( m_trashDir + "/files/boot", 0 );
- TDEIO::NetAccess::del( m_trashDir + "/files/etc", 0 );
-
- //system( "find ~/.local-testtrash/share/Trash" );
-}
-
-void TestTrash::runAll()
-{
- urlTestFile();
- urlTestDirectory();
- urlTestSubDirectory();
-
- trashFileFromHome();
- trashPercentFileFromHome();
-#ifdef UTF8TEST
- trashUtf8FileFromHome();
-#endif
- trashUmlautFileFromHome();
- trashReadOnlyDirFromHome();
- testTrashNotEmpty();
- trashFileFromOther();
- trashFileIntoOtherPartition();
- trashFileOwnedByRoot();
- trashSymlinkFromHome();
- trashSymlinkFromOther();
- trashBrokenSymlinkFromHome();
- trashDirectoryFromHome();
- trashDirectoryFromOther();
- trashDirectoryOwnedByRoot();
-
- tryRenameInsideTrash();
-
- statRoot();
- statFileInRoot();
- statDirectoryInRoot();
- statSymlinkInRoot();
- statFileInDirectory();
-
- copyFileFromTrash();
- // To test case of already-existing destination, uncomment this.
- // This brings up the "rename" dialog though, so it can't be fully automated
- //copyFileFromTrash();
- copyFileInDirectoryFromTrash();
- copyDirectoryFromTrash();
- copySymlinkFromTrash();
-
- moveFileFromTrash();
- moveFileInDirectoryFromTrash();
- moveDirectoryFromTrash();
- moveSymlinkFromTrash();
-
- listRootDir();
- listRecursiveRootDir();
- listSubDir();
-
- delRootFile();
- delFileInDirectory();
- delDirectory();
-
- getFile();
- restoreFile();
- restoreFileFromSubDir();
- restoreFileToDeletedDirectory();
-
- emptyTrash();
-
- // TODO: test
- // - trash migration
- // - the actual updating of the trash icon on the desktop
-}
-
-void TestTrash::urlTestFile()
-{
- const KURL url = TrashImpl::makeURL( 1, "fileId", TQString::null );
- check( "makeURL for a file", url.url(), "trash:/1-fileId" );
-
- int trashId;
- TQString fileId;
- TQString relativePath;
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- assert( ok );
- check( "parseURL: trashId", TQString::number( trashId ), "1" );
- check( "parseURL: fileId", fileId, "fileId" );
- check( "parseURL: relativePath", relativePath, TQString::null );
-}
-
-void TestTrash::urlTestDirectory()
-{
- const KURL url = TrashImpl::makeURL( 1, "fileId", "subfile" );
- check( "makeURL", url.url(), "trash:/1-fileId/subfile" );
-
- int trashId;
- TQString fileId;
- TQString relativePath;
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- assert( ok );
- check( "parseURL: trashId", TQString::number( trashId ), "1" );
- check( "parseURL: fileId", fileId, "fileId" );
- check( "parseURL: relativePath", relativePath, "subfile" );
-}
-
-void TestTrash::urlTestSubDirectory()
-{
- const KURL url = TrashImpl::makeURL( 1, "fileId", "subfile/foobar" );
- check( "makeURL", url.url(), "trash:/1-fileId/subfile/foobar" );
-
- int trashId;
- TQString fileId;
- TQString relativePath;
- bool ok = TrashImpl::parseURL( url, trashId, fileId, relativePath );
- assert( ok );
- check( "parseURL: trashId", TQString::number( trashId ), "1" );
- check( "parseURL: fileId", fileId, "fileId" );
- check( "parseURL: relativePath", relativePath, "subfile/foobar" );
-}
-
-static void checkInfoFile( const TQString& infoPath, const TQString& origFilePath )
-{
- kdDebug() << k_funcinfo << infoPath << endl;
- TQFileInfo info( infoPath );
- assert( info.exists() );
- assert( info.isFile() );
- KSimpleConfig infoFile( info.absFilePath(), true );
- if ( !infoFile.hasGroup( "Trash Info" ) )
- kdFatal() << "no Trash Info group in " << info.absFilePath() << endl;
- infoFile.setGroup( "Trash Info" );
- const TQString origPath = infoFile.readEntry( "Path" );
- assert( !origPath.isEmpty() );
- assert( origPath == KURL::encode_string( origFilePath, TDEGlobal::locale()->fileEncodingMib() ) );
- const TQString date = infoFile.readEntry( "DeletionDate" );
- assert( !date.isEmpty() );
- assert( date.contains( "T" ) );
-}
-
-static void createTestFile( const TQString& path )
-{
- TQFile f( path );
- if ( !f.open( IO_WriteOnly ) )
- kdFatal() << "Can't create " << path << endl;
- f.writeBlock( "Hello world\n", 12 );
- f.close();
- assert( TQFile::exists( path ) );
-}
-
-void TestTrash::trashFile( const TQString& origFilePath, const TQString& fileId )
-{
- // setup
- if ( !TQFile::exists( origFilePath ) )
- createTestFile( origFilePath );
- KURL u;
- u.setPath( origFilePath );
-
- // test
- TDEIO::Job* job = TDEIO::move( u, "trash:/" );
- TQMap<TQString, TQString> metaData;
- //bool ok = TDEIO::NetAccess::move( u, "trash:/" );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
- if ( !ok )
- kdError() << "moving " << u << " to trash failed with error " << TDEIO::NetAccess::lastError() << " " << TDEIO::NetAccess::lastErrorString() << endl;
- assert( ok );
- if ( origFilePath.startsWith( "/tmp" ) && m_tmpIsWritablePartition ) {
- kdDebug() << " TESTS SKIPPED" << endl;
- } else {
- checkInfoFile( m_trashDir + "/info/" + fileId + ".trashinfo", origFilePath );
-
- TQFileInfo files( m_trashDir + "/files/" + fileId );
- assert( files.isFile() );
- assert( files.size() == 12 );
- }
-
- // coolo suggests testing that the original file is actually gone, too :)
- assert( !TQFile::exists( origFilePath ) );
-
- assert( !metaData.isEmpty() );
- bool found = false;
- TQMap<TQString, TQString>::ConstIterator it = metaData.begin();
- for ( ; it != metaData.end() ; ++it ) {
- if ( it.key().startsWith( "trashURL" ) ) {
- const TQString origPath = it.key().mid( 9 );
- KURL trashURL( it.data() );
- kdDebug() << trashURL << endl;
- assert( !trashURL.isEmpty() );
- assert( trashURL.protocol() == "trash" );
- int trashId = 0;
- if ( origFilePath.startsWith( "/tmp" ) && m_tmpIsWritablePartition )
- trashId = m_tmpTrashId;
- assert( trashURL.path() == "/" + TQString::number( trashId ) + "-" + fileId );
- found = true;
- }
- }
- assert( found );
-}
-
-void TestTrash::trashFileFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "fileFromHome";
- trashFile( homeTmpDir() + fileName, fileName );
-
- // Do it again, check that we got a different id
- trashFile( homeTmpDir() + fileName, fileName + "_1" );
-}
-
-void TestTrash::trashPercentFileFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "file%2f";
- trashFile( homeTmpDir() + fileName, fileName );
-}
-
-void TestTrash::trashUtf8FileFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = utf8FileName();
- trashFile( homeTmpDir() + fileName, fileName );
-}
-
-void TestTrash::trashUmlautFileFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = umlautFileName();
- trashFile( homeTmpDir() + fileName, fileName );
-}
-
-void TestTrash::testTrashNotEmpty()
-{
- KSimpleConfig cfg( "trashrc", true );
- assert( cfg.hasGroup( "Status" ) );
- cfg.setGroup( "Status" );
- assert( cfg.readBoolEntry( "Empty", true ) == false );
-}
-
-void TestTrash::trashFileFromOther()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "fileFromOther";
- trashFile( otherTmpDir() + fileName, fileName );
-}
-
-void TestTrash::trashFileIntoOtherPartition()
-{
- if ( m_otherPartitionTrashDir.isEmpty() ) {
- kdDebug() << k_funcinfo << " - SKIPPED" << endl;
- return;
- }
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "testtrash-file";
- const TQString origFilePath = m_otherPartitionTopDir + fileName;
- const TQString fileId = fileName;
- // cleanup
- TQFile::remove( m_otherPartitionTrashDir + "/info/" + fileId + ".trashinfo" );
- TQFile::remove( m_otherPartitionTrashDir + "/files/" + fileId );
-
- // setup
- if ( !TQFile::exists( origFilePath ) )
- createTestFile( origFilePath );
- KURL u;
- u.setPath( origFilePath );
-
- // test
- TDEIO::Job* job = TDEIO::move( u, "trash:/" );
- TQMap<TQString, TQString> metaData;
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
- assert( ok );
- // Note that the Path stored in the info file is relative, on other partitions (#95652)
- checkInfoFile( m_otherPartitionTrashDir + "/info/" + fileId + ".trashinfo", fileName );
-
- TQFileInfo files( m_otherPartitionTrashDir + "/files/" + fileId );
- assert( files.isFile() );
- assert( files.size() == 12 );
-
- // coolo suggests testing that the original file is actually gone, too :)
- assert( !TQFile::exists( origFilePath ) );
-
- assert( !metaData.isEmpty() );
- bool found = false;
- TQMap<TQString, TQString>::ConstIterator it = metaData.begin();
- for ( ; it != metaData.end() ; ++it ) {
- if ( it.key().startsWith( "trashURL" ) ) {
- const TQString origPath = it.key().mid( 9 );
- KURL trashURL( it.data() );
- kdDebug() << trashURL << endl;
- assert( !trashURL.isEmpty() );
- assert( trashURL.protocol() == "trash" );
- assert( trashURL.path() == TQString( "/%1-%2" ).arg( m_otherPartitionId ).arg( fileId ) );
- found = true;
- }
- }
- assert( found );
-}
-
-void TestTrash::trashFileOwnedByRoot()
-{
- kdDebug() << k_funcinfo << endl;
- KURL u;
- u.setPath( "/etc/passwd" );
- const TQString fileId = "passwd";
-
- TDEIO::CopyJob* job = TDEIO::move( u, "trash:/" );
- job->setInteractive( false ); // no skip dialog, thanks
- TQMap<TQString, TQString> metaData;
- //bool ok = TDEIO::NetAccess::move( u, "trash:/" );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
- assert( !ok );
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_ACCESS_DENIED );
- const TQString infoPath( m_trashDir + "/info/" + fileId + ".trashinfo" );
- assert( !TQFile::exists( infoPath ) );
-
- TQFileInfo files( m_trashDir + "/files/" + fileId );
- assert( !files.exists() );
-
- assert( TQFile::exists( u.path() ) );
-}
-
-void TestTrash::trashSymlink( const TQString& origFilePath, const TQString& fileId, bool broken )
-{
- kdDebug() << k_funcinfo << endl;
- // setup
- const char* target = broken ? "/nonexistent" : "/tmp";
- bool ok = ::symlink( target, TQFile::encodeName( origFilePath ) ) == 0;
- assert( ok );
- KURL u;
- u.setPath( origFilePath );
-
- // test
- ok = TDEIO::NetAccess::move( u, "trash:/" );
- assert( ok );
- if ( origFilePath.startsWith( "/tmp" ) && m_tmpIsWritablePartition ) {
- kdDebug() << " TESTS SKIPPED" << endl;
- return;
- }
- checkInfoFile( m_trashDir + "/info/" + fileId + ".trashinfo", origFilePath );
-
- TQFileInfo files( m_trashDir + "/files/" + fileId );
- assert( files.isSymLink() );
- assert( files.readLink() == TQFile::decodeName( target ) );
- assert( !TQFile::exists( origFilePath ) );
-}
-
-void TestTrash::trashSymlinkFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "symlinkFromHome";
- trashSymlink( homeTmpDir() + fileName, fileName, false );
-}
-
-void TestTrash::trashSymlinkFromOther()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "symlinkFromOther";
- trashSymlink( otherTmpDir() + fileName, fileName, false );
-}
-
-void TestTrash::trashBrokenSymlinkFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileName = "brokenSymlinkFromHome";
- trashSymlink( homeTmpDir() + fileName, fileName, true );
-}
-
-void TestTrash::trashDirectory( const TQString& origPath, const TQString& fileId )
-{
- kdDebug() << k_funcinfo << fileId << endl;
- // setup
- if ( !TQFileInfo( origPath ).exists() ) {
- TQDir dir;
- bool ok = dir.mkdir( origPath );
- Q_ASSERT( ok );
- }
- createTestFile( origPath + "/testfile" );
- KURL u; u.setPath( origPath );
-
- // test
- bool ok = TDEIO::NetAccess::move( u, "trash:/" );
- assert( ok );
- if ( origPath.startsWith( "/tmp" ) && m_tmpIsWritablePartition ) {
- kdDebug() << " TESTS SKIPPED" << endl;
- return;
- }
- checkInfoFile( m_trashDir + "/info/" + fileId + ".trashinfo", origPath );
-
- TQFileInfo filesDir( m_trashDir + "/files/" + fileId );
- assert( filesDir.isDir() );
- TQFileInfo files( m_trashDir + "/files/" + fileId + "/testfile" );
- assert( files.exists() );
- assert( files.isFile() );
- assert( files.size() == 12 );
- assert( !TQFile::exists( origPath ) );
-}
-
-void TestTrash::trashDirectoryFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- TQString dirName = "trashDirFromHome";
- trashDirectory( homeTmpDir() + dirName, dirName );
- // Do it again, check that we got a different id
- trashDirectory( homeTmpDir() + dirName, dirName + "_1" );
-}
-
-void TestTrash::trashReadOnlyDirFromHome()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString dirName = readOnlyDirPath();
- TQDir dir;
- bool ok = dir.mkdir( dirName );
- Q_ASSERT( ok );
- // #130780
- const TQString subDirPath = dirName + "/readonly_subdir";
- ok = dir.mkdir( subDirPath );
- Q_ASSERT( ok );
- createTestFile( subDirPath + "/testfile_in_subdir" );
- ::chmod( TQFile::encodeName( subDirPath ), 0500 );
-
- trashDirectory( dirName, "readonly" );
-}
-
-void TestTrash::trashDirectoryFromOther()
-{
- kdDebug() << k_funcinfo << endl;
- TQString dirName = "trashDirFromOther";
- trashDirectory( otherTmpDir() + dirName, dirName );
-}
-
-void TestTrash::tryRenameInsideTrash()
-{
- kdDebug() << k_funcinfo << " with file_move" << endl;
- bool worked = TDEIO::NetAccess::file_move( "trash:/0-tryRenameInsideTrash", "trash:/foobar" );
- assert( !worked );
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_CANNOT_RENAME );
-
- kdDebug() << k_funcinfo << " with move" << endl;
- worked = TDEIO::NetAccess::move( "trash:/0-tryRenameInsideTrash", "trash:/foobar" );
- assert( !worked );
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_CANNOT_RENAME );
-}
-
-void TestTrash::delRootFile()
-{
- kdDebug() << k_funcinfo << endl;
-
- // test deleting a trashed file
- bool ok = TDEIO::NetAccess::del( "trash:/0-fileFromHome", 0L );
- assert( ok );
-
- TQFileInfo file( m_trashDir + "/files/fileFromHome" );
- assert( !file.exists() );
- TQFileInfo info( m_trashDir + "/info/fileFromHome.trashinfo" );
- assert( !info.exists() );
-
- // trash it again, we might need it later
- const TQString fileName = "fileFromHome";
- trashFile( homeTmpDir() + fileName, fileName );
-}
-
-void TestTrash::delFileInDirectory()
-{
- kdDebug() << k_funcinfo << endl;
-
- // test deleting a file inside a trashed directory -> not allowed
- bool ok = TDEIO::NetAccess::del( "trash:/0-trashDirFromHome/testfile", 0L );
- assert( !ok );
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_ACCESS_DENIED );
-
- TQFileInfo dir( m_trashDir + "/files/trashDirFromHome" );
- assert( dir.exists() );
- TQFileInfo file( m_trashDir + "/files/trashDirFromHome/testfile" );
- assert( file.exists() );
- TQFileInfo info( m_trashDir + "/info/trashDirFromHome.trashinfo" );
- assert( info.exists() );
-}
-
-void TestTrash::delDirectory()
-{
- kdDebug() << k_funcinfo << endl;
-
- // test deleting a trashed directory
- bool ok = TDEIO::NetAccess::del( "trash:/0-trashDirFromHome", 0L );
- assert( ok );
-
- TQFileInfo dir( m_trashDir + "/files/trashDirFromHome" );
- assert( !dir.exists() );
- TQFileInfo file( m_trashDir + "/files/trashDirFromHome/testfile" );
- assert( !file.exists() );
- TQFileInfo info( m_trashDir + "/info/trashDirFromHome.trashinfo" );
- assert( !info.exists() );
-
- // trash it again, we'll need it later
- TQString dirName = "trashDirFromHome";
- trashDirectory( homeTmpDir() + dirName, dirName );
-}
-
-void TestTrash::statRoot()
-{
- kdDebug() << k_funcinfo << endl;
- KURL url( "trash:/" );
- TDEIO::UDSEntry entry;
- bool ok = TDEIO::NetAccess::stat( url, entry, 0 );
- assert( ok );
- KFileItem item( entry, url );
- assert( item.isDir() );
- assert( !item.isLink() );
- assert( item.isReadable() );
- assert( item.isWritable() );
- assert( !item.isHidden() );
- assert( item.name() == "." );
- assert( item.acceptsDrops() );
-}
-
-void TestTrash::statFileInRoot()
-{
- kdDebug() << k_funcinfo << endl;
- KURL url( "trash:/0-fileFromHome" );
- TDEIO::UDSEntry entry;
- bool ok = TDEIO::NetAccess::stat( url, entry, 0 );
- assert( ok );
- KFileItem item( entry, url );
- assert( item.isFile() );
- assert( !item.isDir() );
- assert( !item.isLink() );
- assert( item.isReadable() );
- assert( !item.isWritable() );
- assert( !item.isHidden() );
- assert( item.name() == "fileFromHome" );
- assert( !item.acceptsDrops() );
-}
-
-void TestTrash::statDirectoryInRoot()
-{
- kdDebug() << k_funcinfo << endl;
- KURL url( "trash:/0-trashDirFromHome" );
- TDEIO::UDSEntry entry;
- bool ok = TDEIO::NetAccess::stat( url, entry, 0 );
- assert( ok );
- KFileItem item( entry, url );
- assert( item.isDir() );
- assert( !item.isLink() );
- assert( item.isReadable() );
- assert( !item.isWritable() );
- assert( !item.isHidden() );
- assert( item.name() == "trashDirFromHome" );
- assert( !item.acceptsDrops() );
-}
-
-void TestTrash::statSymlinkInRoot()
-{
- kdDebug() << k_funcinfo << endl;
- KURL url( "trash:/0-symlinkFromHome" );
- TDEIO::UDSEntry entry;
- bool ok = TDEIO::NetAccess::stat( url, entry, 0 );
- assert( ok );
- KFileItem item( entry, url );
- assert( item.isLink() );
- assert( item.linkDest() == "/tmp" );
- assert( item.isReadable() );
- assert( !item.isWritable() );
- assert( !item.isHidden() );
- assert( item.name() == "symlinkFromHome" );
- assert( !item.acceptsDrops() );
-}
-
-void TestTrash::statFileInDirectory()
-{
- kdDebug() << k_funcinfo << endl;
- KURL url( "trash:/0-trashDirFromHome/testfile" );
- TDEIO::UDSEntry entry;
- bool ok = TDEIO::NetAccess::stat( url, entry, 0 );
- assert( ok );
- KFileItem item( entry, url );
- assert( item.isFile() );
- assert( !item.isLink() );
- assert( item.isReadable() );
- assert( !item.isWritable() );
- assert( !item.isHidden() );
- assert( item.name() == "testfile" );
- assert( !item.acceptsDrops() );
-}
-
-void TestTrash::copyFromTrash( const TQString& fileId, const TQString& destPath, const TQString& relativePath )
-{
- KURL src( "trash:/0-" + fileId );
- if ( !relativePath.isEmpty() )
- src.addPath( relativePath );
- KURL dest;
- dest.setPath( destPath );
-
- assert( TDEIO::NetAccess::exists( src, true, (TQWidget*)0 ) );
-
- // A dnd would use copy(), but we use copyAs to ensure the final filename
- //kdDebug() << k_funcinfo << "copyAs:" << src << " -> " << dest << endl;
- TDEIO::Job* job = TDEIO::copyAs( src, dest );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
- TQString infoFile( m_trashDir + "/info/" + fileId + ".trashinfo" );
- assert( TQFile::exists( infoFile ) );
-
- TQFileInfo filesItem( m_trashDir + "/files/" + fileId );
- assert( filesItem.exists() );
-
- assert( TQFile::exists( destPath ) );
-}
-
-void TestTrash::copyFileFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "fileFromHome_copied";
- copyFromTrash( "fileFromHome", destPath );
- assert( TQFileInfo( destPath ).isFile() );
- assert( TQFileInfo( destPath ).size() == 12 );
-}
-
-void TestTrash::copyFileInDirectoryFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "testfile_copied";
- copyFromTrash( "trashDirFromHome", destPath, "testfile" );
- assert( TQFileInfo( destPath ).isFile() );
- assert( TQFileInfo( destPath ).size() == 12 );
-}
-
-void TestTrash::copyDirectoryFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "trashDirFromHome_copied";
- copyFromTrash( "trashDirFromHome", destPath );
- assert( TQFileInfo( destPath ).isDir() );
-}
-
-void TestTrash::copySymlinkFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "symlinkFromHome_copied";
- copyFromTrash( "symlinkFromHome", destPath );
- assert( TQFileInfo( destPath ).isSymLink() );
-}
-
-void TestTrash::moveFromTrash( const TQString& fileId, const TQString& destPath, const TQString& relativePath )
-{
- KURL src( "trash:/0-" + fileId );
- if ( !relativePath.isEmpty() )
- src.addPath( relativePath );
- KURL dest;
- dest.setPath( destPath );
-
- assert( TDEIO::NetAccess::exists( src, true, (TQWidget*)0 ) );
-
- // A dnd would use move(), but we use moveAs to ensure the final filename
- TDEIO::Job* job = TDEIO::moveAs( src, dest );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
- TQString infoFile( m_trashDir + "/info/" + fileId + ".trashinfo" );
- assert( !TQFile::exists( infoFile ) );
-
- TQFileInfo filesItem( m_trashDir + "/files/" + fileId );
- assert( !filesItem.exists() );
-
- assert( TQFile::exists( destPath ) );
-}
-
-void TestTrash::moveFileFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "fileFromHome_restored";
- moveFromTrash( "fileFromHome", destPath );
- assert( TQFileInfo( destPath ).isFile() );
- assert( TQFileInfo( destPath ).size() == 12 );
-
- // trash it again for later
- const TQString fileName = "fileFromHome";
- trashFile( homeTmpDir() + fileName, fileName );
-}
-
-void TestTrash::moveFileInDirectoryFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "testfile_restored";
- copyFromTrash( "trashDirFromHome", destPath, "testfile" );
- assert( TQFileInfo( destPath ).isFile() );
- assert( TQFileInfo( destPath ).size() == 12 );
-}
-
-void TestTrash::moveDirectoryFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "trashDirFromHome_restored";
- moveFromTrash( "trashDirFromHome", destPath );
- assert( TQFileInfo( destPath ).isDir() );
-
- // trash it again, we'll need it later
- TQString dirName = "trashDirFromHome";
- trashDirectory( homeTmpDir() + dirName, dirName );
-}
-
-void TestTrash::trashDirectoryOwnedByRoot()
-{
- KURL u;
- if ( TQFile::exists( "/etc/cups" ) )
- u.setPath( "/etc/cups" );
- else if ( TQFile::exists( "/boot" ) )
- u.setPath( "/boot" );
- else
- u.setPath( "/etc" );
- const TQString fileId = u.path();
- kdDebug() << k_funcinfo << "fileId=" << fileId << endl;
-
- TDEIO::CopyJob* job = TDEIO::move( u, "trash:/" );
- job->setInteractive( false ); // no skip dialog, thanks
- TQMap<TQString, TQString> metaData;
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0, 0, 0, &metaData );
- assert( !ok );
- const int err = TDEIO::NetAccess::lastError();
- assert( err == TDEIO::ERR_ACCESS_DENIED
- || err == TDEIO::ERR_CANNOT_OPEN_FOR_READING );
-
- const TQString infoPath( m_trashDir + "/info/" + fileId + ".trashinfo" );
- assert( !TQFile::exists( infoPath ) );
-
- TQFileInfo files( m_trashDir + "/files/" + fileId );
- assert( !files.exists() );
-
- assert( TQFile::exists( u.path() ) );
-}
-
-void TestTrash::moveSymlinkFromTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString destPath = otherTmpDir() + "symlinkFromHome_restored";
- moveFromTrash( "symlinkFromHome", destPath );
- assert( TQFileInfo( destPath ).isSymLink() );
-}
-
-void TestTrash::getFile()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileId = "fileFromHome_1";
- const KURL url = TrashImpl::makeURL( 0, fileId, TQString::null );
- TQString tmpFile;
- bool ok = TDEIO::NetAccess::download( url, tmpFile, 0 );
- assert( ok );
- TQFile file( tmpFile );
- ok = file.open( IO_ReadOnly );
- assert( ok );
- TQByteArray str = file.readAll();
- TQCString cstr( str.data(), str.size() + 1 );
- if ( cstr != "Hello world\n" )
- kdFatal() << "get() returned the following data:" << cstr << endl;
- file.close();
- TDEIO::NetAccess::removeTempFile( tmpFile );
-}
-
-void TestTrash::restoreFile()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileId = "fileFromHome_1";
- const KURL url = TrashImpl::makeURL( 0, fileId, TQString::null );
- const TQString infoFile( m_trashDir + "/info/" + fileId + ".trashinfo" );
- const TQString filesItem( m_trashDir + "/files/" + fileId );
-
- assert( TQFile::exists( infoFile ) );
- assert( TQFile::exists( filesItem ) );
-
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)3 << url;
- TDEIO::Job* job = TDEIO::special( url, packedArgs );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
-
- assert( !TQFile::exists( infoFile ) );
- assert( !TQFile::exists( filesItem ) );
-
- const TQString destPath = homeTmpDir() + "fileFromHome";
- assert( TQFile::exists( destPath ) );
-}
-
-void TestTrash::restoreFileFromSubDir()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString fileId = "trashDirFromHome_1/testfile";
- assert( !TQFile::exists( homeTmpDir() + "trashDirFromHome_1" ) );
-
- const KURL url = TrashImpl::makeURL( 0, fileId, TQString::null );
- const TQString infoFile( m_trashDir + "/info/trashDirFromHome_1.trashinfo" );
- const TQString filesItem( m_trashDir + "/files/trashDirFromHome_1/testfile" );
-
- assert( TQFile::exists( infoFile ) );
- assert( TQFile::exists( filesItem ) );
-
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)3 << url;
- TDEIO::Job* job = TDEIO::special( url, packedArgs );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( !ok );
- // dest dir doesn't exist -> error message
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_SLAVE_DEFINED );
-
- // check that nothing happened
- assert( TQFile::exists( infoFile ) );
- assert( TQFile::exists( filesItem ) );
- assert( !TQFile::exists( homeTmpDir() + "trashDirFromHome_1" ) );
-}
-
-void TestTrash::restoreFileToDeletedDirectory()
-{
- kdDebug() << k_funcinfo << endl;
- // Ensure we'll get "fileFromHome" as fileId
- removeFile( m_trashDir, "/info/fileFromHome.trashinfo" );
- removeFile( m_trashDir, "/files/fileFromHome" );
- trashFileFromHome();
- // Delete orig dir
- bool delOK = TDEIO::NetAccess::del( homeTmpDir(), 0 );
- assert( delOK );
-
- const TQString fileId = "fileFromHome";
- const KURL url = TrashImpl::makeURL( 0, fileId, TQString::null );
- const TQString infoFile( m_trashDir + "/info/" + fileId + ".trashinfo" );
- const TQString filesItem( m_trashDir + "/files/" + fileId );
-
- assert( TQFile::exists( infoFile ) );
- assert( TQFile::exists( filesItem ) );
-
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)3 << url;
- TDEIO::Job* job = TDEIO::special( url, packedArgs );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( !ok );
- // dest dir doesn't exist -> error message
- assert( TDEIO::NetAccess::lastError() == TDEIO::ERR_SLAVE_DEFINED );
-
- // check that nothing happened
- assert( TQFile::exists( infoFile ) );
- assert( TQFile::exists( filesItem ) );
-
- const TQString destPath = homeTmpDir() + "fileFromHome";
- assert( !TQFile::exists( destPath ) );
-}
-
-void TestTrash::listRootDir()
-{
- kdDebug() << k_funcinfo << endl;
- m_entryCount = 0;
- m_listResult.clear();
- TDEIO::ListJob* job = TDEIO::listDir( "trash:/" );
- connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ),
- TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
- kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl;
- assert( m_entryCount > 1 );
-
- kdDebug() << k_funcinfo << m_listResult << endl;
- assert( m_listResult.contains( "." ) == 1 ); // found it, and only once
-}
-
-void TestTrash::listRecursiveRootDir()
-{
- kdDebug() << k_funcinfo << endl;
- m_entryCount = 0;
- m_listResult.clear();
- TDEIO::ListJob* job = TDEIO::listRecursive( "trash:/" );
- connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ),
- TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
- kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl;
- assert( m_entryCount > 1 );
-
- kdDebug() << k_funcinfo << m_listResult << endl;
- assert( m_listResult.contains( "." ) == 1 ); // found it, and only once
-}
-
-void TestTrash::listSubDir()
-{
- kdDebug() << k_funcinfo << endl;
- m_entryCount = 0;
- m_listResult.clear();
- TDEIO::ListJob* job = TDEIO::listDir( "trash:/0-trashDirFromHome" );
- connect( job, TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ),
- TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& ) ) );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
- kdDebug() << "listDir done - m_entryCount=" << m_entryCount << endl;
- assert( m_entryCount == 2 );
-
- kdDebug() << k_funcinfo << m_listResult << endl;
- assert( m_listResult.contains( "." ) == 1 ); // found it, and only once
- assert( m_listResult.contains( "testfile" ) == 1 ); // found it, and only once
-}
-
-void TestTrash::slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& lst )
-{
- for( TDEIO::UDSEntryList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
- TDEIO::UDSEntry::ConstIterator it2 = (*it).begin();
- TQString displayName;
- KURL url;
- for( ; it2 != (*it).end(); it2++ ) {
- switch ((*it2).m_uds) {
- case TDEIO::UDS_NAME:
- displayName = (*it2).m_str;
- break;
- case TDEIO::UDS_URL:
- url = (*it2).m_str;
- break;
- }
- }
- kdDebug() << k_funcinfo << displayName << " " << url << endl;
- if ( !url.isEmpty() ) {
- assert( url.protocol() == "trash" );
- }
- m_listResult << displayName;
- }
- m_entryCount += lst.count();
-}
-
-void TestTrash::emptyTrash()
-{
- // ## Even though we use a custom XDG_DATA_HOME value, emptying the
- // trash would still empty the other trash directories in other partitions.
- // So we can't activate this test by default.
-#if 0
- kdDebug() << k_funcinfo << endl;
- TQByteArray packedArgs;
- TQDataStream stream( packedArgs, IO_WriteOnly );
- stream << (int)1;
- TDEIO::Job* job = TDEIO::special( "trash:/", packedArgs );
- bool ok = TDEIO::NetAccess::synchronousRun( job, 0 );
- assert( ok );
-
- KSimpleConfig cfg( "trashrc", true );
- assert( cfg.hasGroup( "Status" ) );
- cfg.setGroup( "Status" );
- assert( cfg.readBoolEntry( "Empty", false ) == true );
-
- assert( !TQFile::exists( m_trashDir + "/files/fileFromHome" ) );
- assert( !TQFile::exists( m_trashDir + "/files/readonly" ) );
- assert( !TQFile::exists( m_trashDir + "/info/readonly.trashinfo" ) );
-
-#else
- kdDebug() << k_funcinfo << " : SKIPPED" << endl;
-#endif
-}
-
-#include "testtrash.moc"
diff --git a/kioslave/trash/testtrash.h b/kioslave/trash/testtrash.h
deleted file mode 100644
index ebc217aac..000000000
--- a/kioslave/trash/testtrash.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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 TESTTRASH_H
-#define TESTTRASH_H
-
-#include <tqobject.h>
-
-class TestTrash : public QObject
-{
- Q_OBJECT
-
-public:
- TestTrash() {}
- void setup();
- void cleanTrash();
- void runAll();
-
- // tests
-
- void urlTestFile();
- void urlTestDirectory();
- void urlTestSubDirectory();
-
- void trashFileFromHome();
- void trashPercentFileFromHome();
- void trashUtf8FileFromHome();
- void trashUmlautFileFromHome();
- void testTrashNotEmpty();
- void trashFileFromOther();
- void trashFileIntoOtherPartition();
- void trashFileOwnedByRoot();
- void trashSymlinkFromHome();
- void trashSymlinkFromOther();
- void trashBrokenSymlinkFromHome();
- void trashDirectoryFromHome();
- void trashReadOnlyDirFromHome();
- void trashDirectoryFromOther();
- void trashDirectoryOwnedByRoot();
-
- void tryRenameInsideTrash();
-
- void statRoot();
- void statFileInRoot();
- void statDirectoryInRoot();
- void statSymlinkInRoot();
- void statFileInDirectory();
-
- void copyFileFromTrash();
- void copyFileInDirectoryFromTrash();
- void copyDirectoryFromTrash();
- void copySymlinkFromTrash();
-
- void moveFileFromTrash();
- void moveFileInDirectoryFromTrash();
- void moveDirectoryFromTrash();
- void moveSymlinkFromTrash();
-
- void listRootDir();
- void listRecursiveRootDir();
- void listSubDir();
-
- void delRootFile();
- void delFileInDirectory();
- void delDirectory();
-
- void getFile();
- void restoreFile();
- void restoreFileFromSubDir();
- void restoreFileToDeletedDirectory();
-
- void emptyTrash();
-
-private slots:
- void slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& );
-
-private:
- void trashFile( const TQString& origFilePath, const TQString& fileId );
- void trashSymlink( const TQString& origFilePath, const TQString& fileName, bool broken );
- void trashDirectory( const TQString& origPath, const TQString& fileName );
- void copyFromTrash( const TQString& fileId, const TQString& destPath, const TQString& relativePath = TQString::null );
- void moveFromTrash( const TQString& fileId, const TQString& destPath, const TQString& relativePath = TQString::null );
-
- TQString homeTmpDir() const;
- TQString otherTmpDir() const;
- TQString utf8FileName() const;
- TQString umlautFileName() const;
- TQString readOnlyDirPath() const;
-
- TQString m_trashDir;
-
- TQString m_otherPartitionTopDir;
- TQString m_otherPartitionTrashDir;
- bool m_tmpIsWritablePartition;
- int m_tmpTrashId;
- int m_otherPartitionId;
-
- int m_entryCount;
- TQStringList m_listResult;
-};
-
-#endif
diff --git a/kioslave/trash/trash.protocol b/kioslave/trash/trash.protocol
deleted file mode 100644
index 8387fdcb7..000000000
--- a/kioslave/trash/trash.protocol
+++ /dev/null
@@ -1,89 +0,0 @@
-[Protocol]
-exec=kio_trash
-protocol=trash
-input=none
-output=filesystem
-# AccessDate doesn't make sense.
-# OTOH we need deletion date :)
-listing=Name,Type,Size,Extra1,Extra2,Date,Access,Owner,Group,Link
-reading=true
-writing=true
-makedir=false
-deleting=true
-linking=false
-moving=true
-Icon=trashcan_full
-maxInstances=2
-Class=:local
-renameFromFile=true
-renameToFile=true
-copyFromFile=true
-copyToFile=true
-deleteRecursive=true
-fileNameUsedForCopying=Name
-#TODO DocPath
-ExtraNames=Original Path,Deletion Date
-ExtraNames[af]=Oorspronklike gids, Uitvee datum
-ExtraNames[ar]=المسار الأصلي ، تاريخ المحو
-ExtraNames[be]=Арыгінальнае месцазнаходжанне,Час выдалення
-ExtraNames[bg]=Местоположение, дата на изтриване
-ExtraNames[bn]=পূর্বতন পাথ, মোছার তারিখ
-ExtraNames[bs]=Originalni put,Datum brisanja
-ExtraNames[ca]=Camí original,Data d'esborrat
-ExtraNames[cs]=Původní cesta,Datum smazání
-ExtraNames[csb]=Òriginalnô stegna,Datum remniãcô
-ExtraNames[da]=Original sti, sletningsdato
-ExtraNames[de]=Ursprünglicher Pfad, Löschzeitpunkt
-ExtraNames[el]=Αρχική διαδρομή,Ημερομηνία διαγραφής
-ExtraNames[eo]=Originala Vojo,Forigo Dato
-ExtraNames[es]=Ruta original,Fecha de borrado
-ExtraNames[et]=Algne asukoht,Kustutamisaeg
-ExtraNames[eu]=Jatorrizko bideizena, ezabatzeko data
-ExtraNames[fa]=مسیر اصلی، تاریخ حذف
-ExtraNames[fi]=Alkuperäinen polku, poistopäivä
-ExtraNames[fr]=Emplacement d'origine, date de suppression
-ExtraNames[fy]=Oarspronklike lokaasje,datum fan wiskjen
-ExtraNames[ga]=Bunchonair,Dáta Scriosta
-ExtraNames[gl]=Rota Orixinal,Data de Eliminación
-ExtraNames[he]=נתיב מקורי, תאריך מחיקה
-ExtraNames[hi]=मूल पथ, मिटाने की तिथि
-ExtraNames[hr]=Izvorna putanja,Datum brisanja
-ExtraNames[hu]=Eredeti elérési út,Törlési dátum
-ExtraNames[is]=Upprunaleg slóð,dagsetning á eyðingu
-ExtraNames[it]=Percorso originale,ora di eliminazione
-ExtraNames[ja]=元のパス,削除日
-ExtraNames[ka]=საწყისი გეზი, წაშლის თარიღი
-ExtraNames[kk]=Бұрынғы жолы, Өшірілген кезі
-ExtraNames[km]=ផ្លូវ​លំនាំដើម កាលបរិច្ឆេទ​លុប
-ExtraNames[ko]=원본 경로,삭제 날짜
-ExtraNames[lt]=Originalus kelias,Trynimo data
-ExtraNames[lv]=Orģinālais ceļš,Dzēšanas datums
-ExtraNames[mk]=Оригинална патека,Датум на бришење
-ExtraNames[ms]=Laluan Asli, Tarikh Penghapusan
-ExtraNames[nb]=Opprinnelig sti, slettedato
-ExtraNames[nds]=Orginaalpadd,Wegdodatum
-ExtraNames[ne]=मौलिक मार्ग, मेट्ने मिति
-ExtraNames[nl]=Oorspronkelijke locatie,Datum van verwijdering
-ExtraNames[nn]=Opprinneleg stig, slettedato
-ExtraNames[pa]=ਅਸਲੀ ਮਾਰਗ,ਹਟਾਉਣ ਮਿਤੀ
-ExtraNames[pl]=Ścieżka oryginalna,Data usunięcia
-ExtraNames[pt]=Localização Original,Data de Remoção
-ExtraNames[pt_BR]=Caminho Original,Data da Remoção
-ExtraNames[ro]=Calea originală,Data ștergerii
-ExtraNames[ru]=Исходный путь, дата удаления
-ExtraNames[rw]=Inzira Mwimerere, Itariki y'Ihanagura
-ExtraNames[sl]=Prvotna pot,Datum brisanja
-ExtraNames[sr]=првобитна путања,датум брисања
-ExtraNames[sr@Latn]=prvobitna putanja,datum brisanja
-ExtraNames[sv]=Ursprunglig sökväg,Borttagsdatum
-ExtraNames[ta]=மூல பாதை,நீக்கப்பட்ட தேதி
-ExtraNames[te]=అసలు దారు, తీసివేసిన తేది
-ExtraNames[th]=พาธเดิม,วันที่ที่ลบ
-ExtraNames[tr]=Orjinal Yol, Silinme Tarihi
-ExtraNames[tt]=Çığanaq Yulı,Beterelü Çağı
-ExtraNames[uk]=Шлях,Дата вилучення
-ExtraNames[vi]=Đường dẫn Trước khi vứt,Ngày Vứt
-ExtraNames[wa]=Oridjinå tchmin,Date di disfaçaedje
-ExtraNames[zh_CN]=原始路径,删除日期
-ExtraNames[zh_TW]=原始路徑,刪除日期
-ExtraTypes=QString,QDateTime
diff --git a/kioslave/trash/trashimpl.cpp b/kioslave/trash/trashimpl.cpp
deleted file mode 100644
index 3e109c119..000000000
--- a/kioslave/trash/trashimpl.cpp
+++ /dev/null
@@ -1,962 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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 "trashimpl.h"
-#include <klocale.h>
-#include <klargefile.h>
-#include <kio/global.h>
-#include <kio/renamedlg.h>
-#include <kio/job.h>
-#include <kdebug.h>
-#include <kurl.h>
-#include <kdirnotify_stub.h>
-#include <kglobal.h>
-#include <kstandarddirs.h>
-#include <kglobalsettings.h>
-#include <kmountpoint.h>
-#include <kfileitem.h>
-#include <kio/chmodjob.h>
-
-#include <dcopref.h>
-
-#include <tqapplication.h>
-#include <tqeventloop.h>
-#include <tqfile.h>
-#include <tqdir.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <errno.h>
-
-TrashImpl::TrashImpl() :
- TQObject(),
- m_lastErrorCode( 0 ),
- m_initStatus( InitToBeDone ),
- m_lastId( 0 ),
- m_homeDevice( 0 ),
- m_trashDirectoriesScanned( false ),
- m_mibEnum( TDEGlobal::locale()->fileEncodingMib() ),
- // not using kio_trashrc since KIO uses that one already for kio_trash
- // so better have a separate one, for faster parsing by e.g. kmimetype.cpp
- m_config( "trashrc" )
-{
- KDE_struct_stat buff;
- if ( KDE_lstat( TQFile::encodeName( TQDir::homeDirPath() ), &buff ) == 0 ) {
- m_homeDevice = buff.st_dev;
- } else {
- kdError() << "Should never happen: couldn't stat $HOME " << strerror( errno ) << endl;
- }
-}
-
-/**
- * Test if a directory exists, create otherwise
- * @param _name full path of the directory
- * @return errorcode, or 0 if the dir was created or existed already
- * Warning, don't use return value like a bool
- */
-int TrashImpl::testDir( const TQString &_name ) const
-{
- DIR *dp = opendir( TQFile::encodeName(_name) );
- if ( dp == NULL )
- {
- TQString name = _name;
- if ( name.endsWith( "/" ) )
- name.truncate( name.length() - 1 );
- TQCString path = TQFile::encodeName(name);
-
- bool ok = ::mkdir( path, S_IRWXU ) == 0;
- if ( !ok && errno == EEXIST ) {
-#if 0 // this would require to use SlaveBase's method to ask the question
- //int ret = KMessageBox::warningYesNo( 0, i18n("%1 is a file, but TDE needs it to be a directory. Move it to %2.orig and create directory?").arg(name).arg(name) );
- //if ( ret == KMessageBox::Yes ) {
-#endif
- if ( ::rename( path, path + ".orig" ) == 0 ) {
- ok = ::mkdir( path, S_IRWXU ) == 0;
- } else { // foo.orig existed already. How likely is that?
- ok = false;
- }
- if ( !ok ) {
- return TDEIO::ERR_DIR_ALREADY_EXIST;
- }
-#if 0
- //} else {
- // return 0;
- //}
-#endif
- }
- if ( !ok )
- {
- //KMessageBox::sorry( 0, i18n( "Couldn't create directory %1. Check for permissions." ).arg( name ) );
- kdWarning() << "could not create " << name << endl;
- return TDEIO::ERR_COULD_NOT_MKDIR;
- } else {
- kdDebug() << name << " created." << endl;
- }
- }
- else // exists already
- {
- closedir( dp );
- }
- return 0; // success
-}
-
-bool TrashImpl::init()
-{
- if ( m_initStatus == InitOK )
- return true;
- if ( m_initStatus == InitError )
- return false;
-
- // Check the trash directory and its info and files subdirs
- // see also kdesktop/init.cc for first time initialization
- m_initStatus = InitError;
- // $XDG_DATA_HOME/Trash, i.e. ~/.local/share/Trash by default.
- const TQString xdgDataDir = TDEGlobal::dirs()->localxdgdatadir();
- if ( !KStandardDirs::makeDir( xdgDataDir, 0700 ) ) {
- kdWarning() << "failed to create " << xdgDataDir << endl;
- return false;
- }
-
- const TQString trashDir = xdgDataDir + "Trash";
- int err;
- if ( ( err = testDir( trashDir ) ) ) {
- error( err, trashDir );
- return false;
- }
- if ( ( err = testDir( trashDir + "/info" ) ) ) {
- error( err, trashDir + "/info" );
- return false;
- }
- if ( ( err = testDir( trashDir + "/files" ) ) ) {
- error( err, trashDir + "/files" );
- return false;
- }
- m_trashDirectories.insert( 0, trashDir );
- m_initStatus = InitOK;
- kdDebug() << k_funcinfo << "initialization OK, home trash dir: " << trashDir << endl;
- return true;
-}
-
-void TrashImpl::migrateOldTrash()
-{
- kdDebug() << k_funcinfo << endl;
- const TQString oldTrashDir = TDEGlobalSettings::trashPath();
- const TQStrList entries = listDir( oldTrashDir );
- bool allOK = true;
- TQStrListIterator entryIt( entries );
- for (; entryIt.current(); ++entryIt) {
- TQString srcPath = TQFile::decodeName( *entryIt );
- if ( srcPath == "." || srcPath == ".." || srcPath == ".directory" )
- continue;
- srcPath.prepend( oldTrashDir ); // make absolute
- int trashId;
- TQString fileId;
- if ( !createInfo( srcPath, trashId, fileId ) ) {
- kdWarning() << "Trash migration: failed to create info for " << srcPath << endl;
- allOK = false;
- } else {
- bool ok = moveToTrash( srcPath, trashId, fileId );
- if ( !ok ) {
- (void)deleteInfo( trashId, fileId );
- kdWarning() << "Trash migration: failed to create info for " << srcPath << endl;
- allOK = false;
- } else {
- kdDebug() << "Trash migration: moved " << srcPath << endl;
- }
- }
- }
- if ( allOK ) {
- // We need to remove the old one, otherwise the desktop will have two trashcans...
- kdDebug() << "Trash migration: all OK, removing old trash directory" << endl;
- synchronousDel( oldTrashDir, false, true );
- }
-}
-
-bool TrashImpl::createInfo( const TQString& origPath, int& trashId, TQString& fileId )
-{
- kdDebug() << k_funcinfo << origPath << endl;
- // Check source
- const TQCString origPath_c( TQFile::encodeName( origPath ) );
- KDE_struct_stat buff_src;
- if ( KDE_lstat( origPath_c.data(), &buff_src ) == -1 ) {
- if ( errno == EACCES )
- error( TDEIO::ERR_ACCESS_DENIED, origPath );
- else
- error( TDEIO::ERR_DOES_NOT_EXIST, origPath );
- return false;
- }
-
- // Choose destination trash
- trashId = findTrashDirectory( origPath );
- if ( trashId < 0 ) {
- kdWarning() << "OUCH - internal error, TrashImpl::findTrashDirectory returned " << trashId << endl;
- return false; // ### error() needed?
- }
- kdDebug() << k_funcinfo << "trashing to " << trashId << endl;
-
- // Grab original filename
- KURL url;
- url.setPath( origPath );
- const TQString origFileName = url.fileName();
-
- // Make destination file in info/
- url.setPath( infoPath( trashId, origFileName ) ); // we first try with origFileName
- KURL baseDirectory;
- baseDirectory.setPath( url.directory() );
- // Here we need to use O_EXCL to avoid race conditions with other kioslave processes
- int fd = 0;
- do {
- kdDebug() << k_funcinfo << "trying to create " << url.path() << endl;
- fd = ::open( TQFile::encodeName( url.path() ), O_WRONLY | O_CREAT | O_EXCL, 0600 );
- if ( fd < 0 ) {
- if ( errno == EEXIST ) {
- url.setFileName( TDEIO::RenameDlg::suggestName( baseDirectory, url.fileName() ) );
- // and try again on the next iteration
- } else {
- error( TDEIO::ERR_COULD_NOT_WRITE, url.path() );
- return false;
- }
- }
- } while ( fd < 0 );
- const TQString infoPath = url.path();
- fileId = url.fileName();
- Q_ASSERT( fileId.endsWith( ".trashinfo" ) );
- fileId.truncate( fileId.length() - 10 ); // remove .trashinfo from fileId
-
- FILE* file = ::fdopen( fd, "w" );
- if ( !file ) { // can't see how this would happen
- error( TDEIO::ERR_COULD_NOT_WRITE, infoPath );
- return false;
- }
-
- // Contents of the info file. We could use KSimpleConfig, but that would
- // mean closing and reopening fd, i.e. opening a race condition...
- TQCString info = "[Trash Info]\n";
- info += "Path=";
- // Escape filenames according to the way they are encoded on the filesystem
- // All this to basically get back to the raw 8-bit representation of the filename...
- if ( trashId == 0 ) // home trash: absolute path
- info += KURL::encode_string( origPath, m_mibEnum ).latin1();
- else
- info += KURL::encode_string( makeRelativePath( topDirectoryPath( trashId ), origPath ), m_mibEnum ).latin1();
- info += "\n";
- info += "DeletionDate=";
- info += TQDateTime::currentDateTime().toString( Qt::ISODate ).latin1();
- info += "\n";
- size_t sz = info.size() - 1; // avoid trailing 0 from QCString
-
- size_t written = ::fwrite(info.data(), 1, sz, file);
- if ( written != sz ) {
- ::fclose( file );
- TQFile::remove( infoPath );
- error( TDEIO::ERR_DISK_FULL, infoPath );
- return false;
- }
-
- ::fclose( file );
-
- kdDebug() << k_funcinfo << "info file created in trashId=" << trashId << " : " << fileId << endl;
- return true;
-}
-
-TQString TrashImpl::makeRelativePath( const TQString& topdir, const TQString& path )
-{
- const TQString realPath = KStandardDirs::realFilePath( path );
- // topdir ends with '/'
- if ( realPath.startsWith( topdir ) ) {
- const TQString rel = realPath.mid( topdir.length() );
- Q_ASSERT( rel[0] != '/' );
- return rel;
- } else { // shouldn't happen...
- kdWarning() << "Couldn't make relative path for " << realPath << " (" << path << "), with topdir=" << topdir << endl;
- return realPath;
- }
-}
-
-TQString TrashImpl::infoPath( int trashId, const TQString& fileId ) const
-{
- TQString trashPath = trashDirectoryPath( trashId );
- trashPath += "/info/";
- trashPath += fileId;
- trashPath += ".trashinfo";
- return trashPath;
-}
-
-TQString TrashImpl::filesPath( int trashId, const TQString& fileId ) const
-{
- TQString trashPath = trashDirectoryPath( trashId );
- trashPath += "/files/";
- trashPath += fileId;
- return trashPath;
-}
-
-bool TrashImpl::deleteInfo( int trashId, const TQString& fileId )
-{
- bool ok = TQFile::remove( infoPath( trashId, fileId ) );
- if ( ok )
- fileRemoved();
- return ok;
-}
-
-bool TrashImpl::moveToTrash( const TQString& origPath, int trashId, const TQString& fileId )
-{
- kdDebug() << k_funcinfo << endl;
- const TQString dest = filesPath( trashId, fileId );
- if ( !move( origPath, dest ) ) {
- // Maybe the move failed due to no permissions to delete source.
- // In that case, delete dest to keep things consistent, since KIO doesn't do it.
- if ( TQFileInfo( dest ).isFile() )
- TQFile::remove( dest );
- else
- synchronousDel( dest, false, true );
- return false;
- }
- fileAdded();
- return true;
-}
-
-bool TrashImpl::moveFromTrash( const TQString& dest, int trashId, const TQString& fileId, const TQString& relativePath )
-{
- TQString src = filesPath( trashId, fileId );
- if ( !relativePath.isEmpty() ) {
- src += '/';
- src += relativePath;
- }
- if ( !move( src, dest ) )
- return false;
- return true;
-}
-
-bool TrashImpl::move( const TQString& src, const TQString& dest )
-{
- if ( directRename( src, dest ) ) {
- // This notification is done by TDEIO::moveAs when using the code below
- // But if we do a direct rename we need to do the notification ourselves
- KDirNotify_stub allDirNotify( "*", "KDirNotify*" );
- KURL urlDest; urlDest.setPath( dest );
- urlDest.setPath( urlDest.directory() );
- allDirNotify.FilesAdded( urlDest );
- return true;
- }
- if ( m_lastErrorCode != TDEIO::ERR_UNSUPPORTED_ACTION )
- return false;
-
- KURL urlSrc, urlDest;
- urlSrc.setPath( src );
- urlDest.setPath( dest );
- kdDebug() << k_funcinfo << urlSrc << " -> " << urlDest << endl;
- TDEIO::CopyJob* job = TDEIO::moveAs( urlSrc, urlDest, false );
-#ifdef KIO_COPYJOB_HAS_SETINTERACTIVE
- job->setInteractive( false );
-#endif
- connect( job, TQT_SIGNAL( result(TDEIO::Job *) ),
- this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
- tqApp->eventLoop()->enterLoop();
-
- return m_lastErrorCode == 0;
-}
-
-void TrashImpl::jobFinished(TDEIO::Job* job)
-{
- kdDebug() << k_funcinfo << " error=" << job->error() << endl;
- error( job->error(), job->errorText() );
- tqApp->eventLoop()->exitLoop();
-}
-
-bool TrashImpl::copyToTrash( const TQString& origPath, int trashId, const TQString& fileId )
-{
- kdDebug() << k_funcinfo << endl;
- const TQString dest = filesPath( trashId, fileId );
- if ( !copy( origPath, dest ) )
- return false;
- fileAdded();
- return true;
-}
-
-bool TrashImpl::copyFromTrash( const TQString& dest, int trashId, const TQString& fileId, const TQString& relativePath )
-{
- TQString src = filesPath( trashId, fileId );
- if ( !relativePath.isEmpty() ) {
- src += '/';
- src += relativePath;
- }
- return copy( src, dest );
-}
-
-bool TrashImpl::copy( const TQString& src, const TQString& dest )
-{
- // kio_file's copy() method is quite complex (in order to be fast), let's just call it...
- m_lastErrorCode = 0;
- KURL urlSrc;
- urlSrc.setPath( src );
- KURL urlDest;
- urlDest.setPath( dest );
- kdDebug() << k_funcinfo << "copying " << src << " to " << dest << endl;
- TDEIO::CopyJob* job = TDEIO::copyAs( urlSrc, urlDest, false );
-#ifdef KIO_COPYJOB_HAS_SETINTERACTIVE
- job->setInteractive( false );
-#endif
- connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
- this, TQT_SLOT( jobFinished( TDEIO::Job* ) ) );
- tqApp->eventLoop()->enterLoop();
-
- return m_lastErrorCode == 0;
-}
-
-bool TrashImpl::directRename( const TQString& src, const TQString& dest )
-{
- kdDebug() << k_funcinfo << src << " -> " << dest << endl;
- if ( ::rename( TQFile::encodeName( src ), TQFile::encodeName( dest ) ) != 0 ) {
- if (errno == EXDEV) {
- error( TDEIO::ERR_UNSUPPORTED_ACTION, TQString::fromLatin1("rename") );
- } else {
- if (( errno == EACCES ) || (errno == EPERM)) {
- error( TDEIO::ERR_ACCESS_DENIED, dest );
- } else if (errno == EROFS) { // The file is on a read-only filesystem
- error( TDEIO::ERR_CANNOT_DELETE, src );
- } else {
- error( TDEIO::ERR_CANNOT_RENAME, src );
- }
- }
- return false;
- }
- return true;
-}
-
-#if 0
-bool TrashImpl::mkdir( int trashId, const TQString& fileId, int permissions )
-{
- const TQString path = filesPath( trashId, fileId );
- if ( ::mkdir( TQFile::encodeName( path ), permissions ) != 0 ) {
- if ( errno == EACCES ) {
- error( TDEIO::ERR_ACCESS_DENIED, path );
- return false;
- } else if ( errno == ENOSPC ) {
- error( TDEIO::ERR_DISK_FULL, path );
- return false;
- } else {
- error( TDEIO::ERR_COULD_NOT_MKDIR, path );
- return false;
- }
- } else {
- if ( permissions != -1 )
- ::chmod( TQFile::encodeName( path ), permissions );
- }
- return true;
-}
-#endif
-
-bool TrashImpl::del( int trashId, const TQString& fileId )
-{
- TQString info = infoPath(trashId, fileId);
- TQString file = filesPath(trashId, fileId);
-
- TQCString info_c = TQFile::encodeName(info);
-
- KDE_struct_stat buff;
- if ( KDE_lstat( info_c.data(), &buff ) == -1 ) {
- if ( errno == EACCES )
- error( TDEIO::ERR_ACCESS_DENIED, file );
- else
- error( TDEIO::ERR_DOES_NOT_EXIST, file );
- return false;
- }
-
- if ( !synchronousDel( file, true, TQFileInfo(file).isDir() ) )
- return false;
-
- TQFile::remove( info );
- fileRemoved();
- return true;
-}
-
-bool TrashImpl::synchronousDel( const TQString& path, bool setLastErrorCode, bool isDir )
-{
- const int oldErrorCode = m_lastErrorCode;
- const TQString oldErrorMsg = m_lastErrorMessage;
- KURL url;
- url.setPath( path );
-
- // First ensure that all dirs have u+w permissions,
- // otherwise we won't be able to delete files in them (#130780).
- if ( isDir ) {
- kdDebug() << k_funcinfo << "chmod'ing " << url << endl;
- KFileItem fileItem( url, "inode/directory", KFileItem::Unknown );
- KFileItemList fileItemList;
- fileItemList.append( &fileItem );
- TDEIO::ChmodJob* chmodJob = TDEIO::chmod( fileItemList, 0200, 0200, TQString::null, TQString::null, true /*recursive*/, false /*showProgressInfo*/ );
- connect( chmodJob, TQT_SIGNAL( result(TDEIO::Job *) ),
- this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
- tqApp->eventLoop()->enterLoop();
- }
-
- kdDebug() << k_funcinfo << "deleting " << url << endl;
- TDEIO::DeleteJob *job = TDEIO::del( url, false, false );
- connect( job, TQT_SIGNAL( result(TDEIO::Job *) ),
- this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
- tqApp->eventLoop()->enterLoop();
- bool ok = m_lastErrorCode == 0;
- if ( !setLastErrorCode ) {
- m_lastErrorCode = oldErrorCode;
- m_lastErrorMessage = oldErrorMsg;
- }
- return ok;
-}
-
-bool TrashImpl::emptyTrash()
-{
- kdDebug() << k_funcinfo << endl;
- // The naive implementation "delete info and files in every trash directory"
- // breaks when deleted directories contain files owned by other users.
- // We need to ensure that the .trashinfo file is only removed when the
- // corresponding files could indeed be removed.
-
- const TrashedFileInfoList fileInfoList = list();
-
- TrashedFileInfoList::const_iterator it = fileInfoList.begin();
- const TrashedFileInfoList::const_iterator end = fileInfoList.end();
- for ( ; it != end ; ++it ) {
- const TrashedFileInfo& info = *it;
- const TQString filesPath = info.physicalPath;
- if ( synchronousDel( filesPath, true, true ) ) {
- TQFile::remove( infoPath( info.trashId, info.fileId ) );
- } // else error code is set
- }
- fileRemoved();
-
- return m_lastErrorCode == 0;
-}
-
-TrashImpl::TrashedFileInfoList TrashImpl::list()
-{
- // Here we scan for trash directories unconditionally. This allows
- // noticing plugged-in [e.g. removeable] devices, or new mounts etc.
- scanTrashDirectories();
-
- TrashedFileInfoList lst;
- // For each known trash directory...
- TrashDirMap::const_iterator it = m_trashDirectories.begin();
- for ( ; it != m_trashDirectories.end() ; ++it ) {
- const int trashId = it.key();
- TQString infoPath = it.data();
- infoPath += "/info";
- // Code taken from kio_file
- TQStrList entryNames = listDir( infoPath );
- //char path_buffer[PATH_MAX];
- //getcwd(path_buffer, PATH_MAX - 1);
- //if ( chdir( infoPathEnc ) )
- // continue;
- TQStrListIterator entryIt( entryNames );
- for (; entryIt.current(); ++entryIt) {
- TQString fileName = TQFile::decodeName( *entryIt );
- if ( fileName == "." || fileName == ".." )
- continue;
- if ( !fileName.endsWith( ".trashinfo" ) ) {
- kdWarning() << "Invalid info file found in " << infoPath << " : " << fileName << endl;
- continue;
- }
- fileName.truncate( fileName.length() - 10 );
-
- TrashedFileInfo info;
- if ( infoForFile( trashId, fileName, info ) )
- lst << info;
- }
- }
- return lst;
-}
-
-// Returns the entries in a given directory - including "." and ".."
-TQStrList TrashImpl::listDir( const TQString& physicalPath )
-{
- const TQCString physicalPathEnc = TQFile::encodeName( physicalPath );
- kdDebug() << k_funcinfo << "listing " << physicalPath << endl;
- TQStrList entryNames;
- DIR *dp = opendir( physicalPathEnc );
- if ( dp == 0 )
- return entryNames;
- KDE_struct_dirent *ep;
- while ( ( ep = KDE_readdir( dp ) ) != 0L )
- entryNames.append( ep->d_name );
- closedir( dp );
- return entryNames;
-}
-
-bool TrashImpl::infoForFile( int trashId, const TQString& fileId, TrashedFileInfo& info )
-{
- kdDebug() << k_funcinfo << trashId << " " << fileId << endl;
- info.trashId = trashId; // easy :)
- info.fileId = fileId; // equally easy
- info.physicalPath = filesPath( trashId, fileId );
- return readInfoFile( infoPath( trashId, fileId ), info, trashId );
-}
-
-bool TrashImpl::readInfoFile( const TQString& infoPath, TrashedFileInfo& info, int trashId )
-{
- KSimpleConfig cfg( infoPath, true );
- if ( !cfg.hasGroup( "Trash Info" ) ) {
- error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, infoPath );
- return false;
- }
- cfg.setGroup( "Trash Info" );
- info.origPath = KURL::decode_string( cfg.readEntry( "Path" ), m_mibEnum );
- if ( info.origPath.isEmpty() )
- return false; // path is mandatory...
- if ( trashId == 0 )
- Q_ASSERT( info.origPath[0] == '/' );
- else {
- const TQString topdir = topDirectoryPath( trashId ); // includes trailing slash
- info.origPath.prepend( topdir );
- }
- TQString line = cfg.readEntry( "DeletionDate" );
- if ( !line.isEmpty() ) {
- info.deletionDate = TQT_TQDATETIME_OBJECT(TQDateTime::fromString( line, Qt::ISODate ));
- }
- return true;
-}
-
-TQString TrashImpl::physicalPath( int trashId, const TQString& fileId, const TQString& relativePath )
-{
- TQString filePath = filesPath( trashId, fileId );
- if ( !relativePath.isEmpty() ) {
- filePath += "/";
- filePath += relativePath;
- }
- return filePath;
-}
-
-void TrashImpl::error( int e, const TQString& s )
-{
- if ( e )
- kdDebug() << k_funcinfo << e << " " << s << endl;
- m_lastErrorCode = e;
- m_lastErrorMessage = s;
-}
-
-bool TrashImpl::isEmpty() const
-{
- // For each known trash directory...
- if ( !m_trashDirectoriesScanned )
- scanTrashDirectories();
- TrashDirMap::const_iterator it = m_trashDirectories.begin();
- for ( ; it != m_trashDirectories.end() ; ++it ) {
- TQString infoPath = it.data();
- infoPath += "/info";
-
- DIR *dp = opendir( TQFile::encodeName( infoPath ) );
- if ( dp )
- {
- struct dirent *ep;
- ep = readdir( dp );
- ep = readdir( dp ); // ignore '.' and '..' dirent
- ep = readdir( dp ); // look for third file
- closedir( dp );
- if ( ep != 0 ) {
- //kdDebug() << ep->d_name << " in " << infoPath << " -> not empty" << endl;
- return false; // not empty
- }
- }
- }
- return true;
-}
-
-void TrashImpl::fileAdded()
-{
- m_config.setGroup( "Status" );
- if ( m_config.readBoolEntry( "Empty", true ) == true ) {
- m_config.writeEntry( "Empty", false );
- m_config.sync();
- }
- // The apps showing the trash (e.g. kdesktop) will be notified
- // of this change when KDirNotify::FilesAdded("trash:/") is emitted,
- // which will be done by the job soon after this.
-}
-
-void TrashImpl::fileRemoved()
-{
- if ( isEmpty() ) {
- m_config.setGroup( "Status" );
- m_config.writeEntry( "Empty", true );
- m_config.sync();
- }
- // The apps showing the trash (e.g. kdesktop) will be notified
- // of this change when KDirNotify::FilesRemoved(...) is emitted,
- // which will be done by the job soon after this.
-}
-
-int TrashImpl::findTrashDirectory( const TQString& origPath )
-{
- kdDebug() << k_funcinfo << origPath << endl;
- // First check if same device as $HOME, then we use the home trash right away.
- KDE_struct_stat buff;
- if ( KDE_lstat( TQFile::encodeName( origPath ), &buff ) == 0
- && buff.st_dev == m_homeDevice )
- return 0;
-
- TQString mountPoint = TDEIO::findPathMountPoint( origPath );
- const TQString trashDir = trashForMountPoint( mountPoint, true );
- kdDebug() << "mountPoint=" << mountPoint << " trashDir=" << trashDir << endl;
- if ( trashDir.isEmpty() )
- return 0; // no trash available on partition
- int id = idForTrashDirectory( trashDir );
- if ( id > -1 ) {
- kdDebug() << " known with id " << id << endl;
- return id;
- }
- // new trash dir found, register it
- // but we need stability in the trash IDs, so that restoring or asking
- // for properties works even kio_trash gets killed because idle.
-#if 0
- kdDebug() << k_funcinfo << "found " << trashDir << endl;
- m_trashDirectories.insert( ++m_lastId, trashDir );
- if ( !mountPoint.endsWith( "/" ) )
- mountPoint += '/';
- m_topDirectories.insert( m_lastId, mountPoint );
- return m_lastId;
-#endif
- scanTrashDirectories();
- return idForTrashDirectory( trashDir );
-}
-
-void TrashImpl::scanTrashDirectories() const
-{
- const KMountPoint::List lst = KMountPoint::currentMountPoints();
- for ( KMountPoint::List::ConstIterator it = lst.begin() ; it != lst.end() ; ++it ) {
- const TQCString str = (*it)->mountType().latin1();
- // Skip pseudo-filesystems, there's no chance we'll find a .Trash on them :)
- // ## Maybe we should also skip readonly filesystems
- if ( str != "proc" && str != "devfs" && str != "usbdevfs" &&
- str != "sysfs" && str != "devpts" && str != "subfs" /* #96259 */ &&
- str != "autofs" /* #101116 */ ) {
- TQString topdir = (*it)->mountPoint();
- TQString trashDir = trashForMountPoint( topdir, false );
- if ( !trashDir.isEmpty() ) {
- // OK, trashDir is a valid trash directory. Ensure it's registered.
- int trashId = idForTrashDirectory( trashDir );
- if ( trashId == -1 ) {
- // new trash dir found, register it
- m_trashDirectories.insert( ++m_lastId, trashDir );
- kdDebug() << k_funcinfo << "found " << trashDir << " gave it id " << m_lastId << endl;
- if ( !topdir.endsWith( "/" ) )
- topdir += '/';
- m_topDirectories.insert( m_lastId, topdir );
- }
- }
- }
- }
- m_trashDirectoriesScanned = true;
-}
-
-TrashImpl::TrashDirMap TrashImpl::trashDirectories() const
-{
- if ( !m_trashDirectoriesScanned )
- scanTrashDirectories();
- return m_trashDirectories;
-}
-
-TrashImpl::TrashDirMap TrashImpl::topDirectories() const
-{
- if ( !m_trashDirectoriesScanned )
- scanTrashDirectories();
- return m_topDirectories;
-}
-
-TQString TrashImpl::trashForMountPoint( const TQString& topdir, bool createIfNeeded ) const
-{
- // (1) Administrator-created $topdir/.Trash directory
-
- const TQString rootTrashDir = topdir + "/.Trash";
- const TQCString rootTrashDir_c = TQFile::encodeName( rootTrashDir );
- // Can't use TQFileInfo here since we need to test for the sticky bit
- uid_t uid = getuid();
- KDE_struct_stat buff;
- const uint requiredBits = S_ISVTX; // Sticky bit required
- if ( KDE_lstat( rootTrashDir_c, &buff ) == 0 ) {
- if ( (S_ISDIR(buff.st_mode)) // must be a dir
- && (!S_ISLNK(buff.st_mode)) // not a symlink
- && ((buff.st_mode & requiredBits) == requiredBits)
- && (::access(rootTrashDir_c, W_OK))
- ) {
- const TQString trashDir = rootTrashDir + "/" + TQString::number( uid );
- const TQCString trashDir_c = TQFile::encodeName( trashDir );
- if ( KDE_lstat( trashDir_c, &buff ) == 0 ) {
- if ( (buff.st_uid == uid) // must be owned by user
- && (S_ISDIR(buff.st_mode)) // must be a dir
- && (!S_ISLNK(buff.st_mode)) // not a symlink
- && (buff.st_mode & 0777) == 0700 ) { // rwx for user
- return trashDir;
- }
- kdDebug() << "Directory " << trashDir << " exists but didn't pass the security checks, can't use it" << endl;
- }
- else if ( createIfNeeded && initTrashDirectory( trashDir_c ) ) {
- return trashDir;
- }
- } else {
- kdDebug() << "Root trash dir " << rootTrashDir << " exists but didn't pass the security checks, can't use it" << endl;
- }
- }
-
- // (2) $topdir/.Trash-$uid
- const TQString trashDir = topdir + "/.Trash-" + TQString::number( uid );
- const TQCString trashDir_c = TQFile::encodeName( trashDir );
- if ( KDE_lstat( trashDir_c, &buff ) == 0 )
- {
- if ( (buff.st_uid == uid) // must be owned by user
- && (S_ISDIR(buff.st_mode)) // must be a dir
- && (!S_ISLNK(buff.st_mode)) // not a symlink
- && ((buff.st_mode & 0777) == 0700) ) { // rwx for user, ------ for group and others
-
- if ( checkTrashSubdirs( trashDir_c ) )
- return trashDir;
- }
- kdDebug() << "Directory " << trashDir << " exists but didn't pass the security checks, can't use it" << endl;
- // Exists, but not useable
- return TQString::null;
- }
- if ( createIfNeeded && initTrashDirectory( trashDir_c ) ) {
- return trashDir;
- }
- return TQString::null;
-}
-
-int TrashImpl::idForTrashDirectory( const TQString& trashDir ) const
-{
- // If this is too slow we can always use a reverse map...
- TrashDirMap::ConstIterator it = m_trashDirectories.begin();
- for ( ; it != m_trashDirectories.end() ; ++it ) {
- if ( it.data() == trashDir ) {
- return it.key();
- }
- }
- return -1;
-}
-
-bool TrashImpl::initTrashDirectory( const TQCString& trashDir_c ) const
-{
- if ( ::mkdir( trashDir_c, 0700 ) != 0 )
- return false;
- // This trash dir will be useable only if the directory is owned by user.
- // In theory this is the case, but not on e.g. USB keys...
- uid_t uid = getuid();
- KDE_struct_stat buff;
- if ( KDE_lstat( trashDir_c, &buff ) != 0 )
- return false; // huh?
- if ( (buff.st_uid == uid) // must be owned by user
- && ((buff.st_mode & 0777) == 0700) ) { // rwx for user, --- for group and others
-
- return checkTrashSubdirs( trashDir_c );
-
- } else {
- kdDebug() << trashDir_c << " just created, by it doesn't have the right permissions, must be a FAT partition. Removing it again." << endl;
- // Not good, e.g. USB key. Delete again.
- // I'm paranoid, it would be better to find a solution that allows
- // to trash directly onto the USB key, but I don't see how that would
- // pass the security checks. It would also make the USB key appears as
- // empty when it's in fact full...
- ::rmdir( trashDir_c );
- return false;
- }
- return true;
-}
-
-bool TrashImpl::checkTrashSubdirs( const TQCString& trashDir_c ) const
-{
- // testDir currently works with a TQString - ## optimize
- TQString trashDir = TQFile::decodeName( trashDir_c );
- const TQString info = trashDir + "/info";
- if ( testDir( info ) != 0 )
- return false;
- const TQString files = trashDir + "/files";
- if ( testDir( files ) != 0 )
- return false;
- return true;
-}
-
-TQString TrashImpl::trashDirectoryPath( int trashId ) const
-{
- // Never scanned for trash dirs? (This can happen after killing kio_trash
- // and reusing a directory listing from the earlier instance.)
- if ( !m_trashDirectoriesScanned )
- scanTrashDirectories();
- Q_ASSERT( m_trashDirectories.contains( trashId ) );
- return m_trashDirectories[trashId];
-}
-
-TQString TrashImpl::topDirectoryPath( int trashId ) const
-{
- if ( !m_trashDirectoriesScanned )
- scanTrashDirectories();
- assert( trashId != 0 );
- Q_ASSERT( m_topDirectories.contains( trashId ) );
- return m_topDirectories[trashId];
-}
-
-// Helper method. Creates a URL with the format trash:/trashid-fileid or
-// trash:/trashid-fileid/relativePath/To/File for a file inside a trashed directory.
-KURL TrashImpl::makeURL( int trashId, const TQString& fileId, const TQString& relativePath )
-{
- KURL url;
- url.setProtocol( "trash" );
- TQString path = "/";
- path += TQString::number( trashId );
- path += '-';
- path += fileId;
- if ( !relativePath.isEmpty() ) {
- path += '/';
- path += relativePath;
- }
- url.setPath( path );
- return url;
-}
-
-// Helper method. Parses a trash URL with the URL scheme defined in makeURL.
-// The trash:/ URL itself isn't parsed here, must be caught by the caller before hand.
-bool TrashImpl::parseURL( const KURL& url, int& trashId, TQString& fileId, TQString& relativePath )
-{
- if ( url.protocol() != "trash" )
- return false;
- const TQString path = url.path();
- int start = 0;
- if ( path[0] == '/' ) // always true I hope
- start = 1;
- int slashPos = path.find( '-', 0 ); // don't match leading slash
- if ( slashPos <= 0 )
- return false;
- bool ok = false;
- trashId = path.mid( start, slashPos - start ).toInt( &ok );
- Q_ASSERT( ok );
- if ( !ok )
- return false;
- start = slashPos + 1;
- slashPos = path.find( '/', start );
- if ( slashPos <= 0 ) {
- fileId = path.mid( start );
- relativePath = TQString::null;
- return true;
- }
- fileId = path.mid( start, slashPos - start );
- relativePath = path.mid( slashPos + 1 );
- return true;
-}
-
-#include "trashimpl.moc"
diff --git a/kioslave/trash/trashimpl.h b/kioslave/trash/trashimpl.h
deleted file mode 100644
index 366f8a869..000000000
--- a/kioslave/trash/trashimpl.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* This file is part of the KDE project
- Copyright (C) 2004 David Faure <[email protected]>
-
- 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 TRASHIMPL_H
-#define TRASHIMPL_H
-
-#include <kio/jobclasses.h>
-#include <ksimpleconfig.h>
-
-#include <tqstring.h>
-#include <tqdatetime.h>
-#include <tqmap.h>
-#include <tqvaluelist.h>
-#include <tqstrlist.h>
-#include <assert.h>
-
-/**
- * Implementation of all low-level operations done by kio_trash
- * The structure of the trash directory follows the freedesktop.org standard <TODO URL>
- */
-class TrashImpl : public TQObject
-{
- Q_OBJECT
-public:
- TrashImpl();
-
- /// Check the "home" trash directory
- /// This MUST be called before doing anything else
- bool init();
-
- /// Create info for a file to be trashed
- /// Returns trashId and fileId
- /// The caller is then responsible for actually trashing the file
- bool createInfo( const TQString& origPath, int& trashId, TQString& fileId );
-
- /// Delete info file for a file to be trashed
- /// Usually used for undoing what createInfo did if trashing failed
- bool deleteInfo( int trashId, const TQString& fileId );
-
- /// Moving a file or directory into the trash. The ids come from createInfo.
- bool moveToTrash( const TQString& origPath, int trashId, const TQString& fileId );
-
- /// Moving a file or directory out of the trash. The ids come from createInfo.
- bool moveFromTrash( const TQString& origPath, int trashId, const TQString& fileId, const TQString& relativePath );
-
- /// Copying a file or directory into the trash. The ids come from createInfo.
- bool copyToTrash( const TQString& origPath, int trashId, const TQString& fileId );
-
- /// Copying a file or directory out of the trash. The ids come from createInfo.
- bool copyFromTrash( const TQString& origPath, int trashId, const TQString& fileId, const TQString& relativePath );
-
- /// Create a top-level trashed directory
- //bool mkdir( int trashId, const TQString& fileId, int permissions );
-
- /// Get rid of a trashed file
- bool del( int trashId, const TQString& fileId );
-
- /// Empty trash, i.e. delete all trashed files
- bool emptyTrash();
-
- /// Return true if the trash is empty
- bool isEmpty() const;
-
- struct TrashedFileInfo {
- int trashId; // for the url
- TQString fileId; // for the url
- TQString physicalPath; // for stat'ing etc.
- TQString origPath; // from info file
- TQDateTime deletionDate; // from info file
- };
- /// List trashed files
- typedef TQValueList<TrashedFileInfo> TrashedFileInfoList;
- TrashedFileInfoList list();
-
- /// Return the info for a given trashed file
- bool infoForFile( int trashId, const TQString& fileId, TrashedFileInfo& info );
-
- /// Return the physicalPath for a given trashed file - helper method which
- /// encapsulates the call to infoForFile. Don't use if you need more info from TrashedFileInfo.
- TQString physicalPath( int trashId, const TQString& fileId, const TQString& relativePath );
-
- /// Move data from the old trash system to the new one
- void migrateOldTrash();
-
- /// KIO error code
- int lastErrorCode() const { return m_lastErrorCode; }
- TQString lastErrorMessage() const { return m_lastErrorMessage; }
-
- TQStrList listDir( const TQString& physicalPath );
-
- static KURL makeURL( int trashId, const TQString& fileId, const TQString& relativePath );
- static bool parseURL( const KURL& url, int& trashId, TQString& fileId, TQString& relativePath );
-
- typedef TQMap<int, TQString> TrashDirMap;
- /// @internal This method is for TestTrash only. Home trash is included (id 0).
- TrashDirMap trashDirectories() const;
- /// @internal This method is for TestTrash only. No entry with id 0.
- TrashDirMap topDirectories() const;
-
-private:
- /// Helper method. Moves a file or directory using the appropriate method.
- bool move( const TQString& src, const TQString& dest );
- bool copy( const TQString& src, const TQString& dest );
- /// Helper method. Tries to call ::rename(src,dest) and does error handling.
- bool directRename( const TQString& src, const TQString& dest );
-
- void fileAdded();
- void fileRemoved();
-
- // Warning, returns error code, not a bool
- int testDir( const TQString& name ) const;
- void error( int e, const TQString& s );
-
- bool readInfoFile( const TQString& infoPath, TrashedFileInfo& info, int trashId );
-
- TQString infoPath( int trashId, const TQString& fileId ) const;
- TQString filesPath( int trashId, const TQString& fileId ) const;
-
- /// Find the trash dir to use for a given file to delete, based on original path
- int findTrashDirectory( const TQString& origPath );
-
- TQString trashDirectoryPath( int trashId ) const;
- TQString topDirectoryPath( int trashId ) const;
-
- bool synchronousDel( const TQString& path, bool setLastErrorCode, bool isDir );
-
- void scanTrashDirectories() const;
-
- int idForTrashDirectory( const TQString& trashDir ) const;
- bool initTrashDirectory( const TQCString& trashDir_c ) const;
- bool checkTrashSubdirs( const TQCString& trashDir_c ) const;
- TQString trashForMountPoint( const TQString& topdir, bool createIfNeeded ) const;
- static TQString makeRelativePath( const TQString& topdir, const TQString& path );
-
-private slots:
- void jobFinished(TDEIO::Job *job);
-
-private:
- /// Last error code stored in class to simplify API.
- /// Note that this means almost no method can be const.
- int m_lastErrorCode;
- TQString m_lastErrorMessage;
-
- enum { InitToBeDone, InitOK, InitError } m_initStatus;
-
- // A "trash directory" is a physical directory on disk,
- // e.g. $HOME/.local/share/Trash/$uid or /mnt/foo/.Trash/$uid
- // It has an id (number) and a path.
- // The home trash has id 0.
- mutable TrashDirMap m_trashDirectories; // id -> path of trash directory
- mutable TrashDirMap m_topDirectories; // id -> $topdir of partition
- mutable int m_lastId;
- dev_t m_homeDevice;
- mutable bool m_trashDirectoriesScanned;
- int m_mibEnum;
-
- KSimpleConfig m_config;
-
- // We don't cache any data related to the trashed files.
- // Another kioslave could change that behind our feet.
- // If we want to start caching data - and avoiding some race conditions -,
- // we should turn this class into a kded module and use DCOP to talk to it
- // from the kioslave.
-};
-
-#endif