From 472156a41b1348c714986c772759ad950fffbe75 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 27 Jan 2013 15:11:21 -0600 Subject: Rename kioslaves --- tdeioslave/DEBUG.howto | 2 +- tdeioslave/DESIGN | 2 +- tdeioslave/about/CMakeLists.txt | 6 +- tdeioslave/about/Makefile.am | 10 +- tdeioslave/about/about.protocol | 2 +- tdeioslave/about/kio_about.cpp | 76 - tdeioslave/about/kio_about.h | 39 - tdeioslave/about/tdeio_about.cpp | 76 + tdeioslave/about/tdeio_about.h | 39 + tdeioslave/cgi/CMakeLists.txt | 4 +- tdeioslave/cgi/Makefile.am | 8 +- tdeioslave/cgi/cgi.cpp | 6 +- tdeioslave/cgi/cgi.protocol | 2 +- tdeioslave/configure.in.in | 2 +- tdeioslave/filter/CMakeLists.txt | 4 +- tdeioslave/filter/Makefile.am | 8 +- tdeioslave/filter/bzip.protocol | 2 +- tdeioslave/filter/bzip2.protocol | 2 +- tdeioslave/filter/filter.cc | 4 +- tdeioslave/filter/gzip.protocol | 2 +- tdeioslave/finger/CMakeLists.txt | 8 +- tdeioslave/finger/Makefile.am | 18 +- tdeioslave/finger/finger.protocol | 2 +- tdeioslave/finger/kio_finger.cpp | 266 --- tdeioslave/finger/kio_finger.css | 69 - tdeioslave/finger/kio_finger.h | 64 - tdeioslave/finger/kio_finger.pl | 175 -- tdeioslave/finger/tdeio_finger.cpp | 266 +++ tdeioslave/finger/tdeio_finger.css | 69 + tdeioslave/finger/tdeio_finger.h | 64 + tdeioslave/finger/tdeio_finger.pl | 175 ++ tdeioslave/fish/CMakeLists.txt | 4 +- tdeioslave/fish/FAQ | 2 +- tdeioslave/fish/Makefile.am | 8 +- tdeioslave/fish/README | 2 +- tdeioslave/fish/fish.cpp | 2 +- tdeioslave/fish/fish.pl | 4 +- tdeioslave/fish/fish.protocol | 2 +- tdeioslave/fish/nxfish.protocol | 2 +- tdeioslave/floppy/CMakeLists.txt | 6 +- tdeioslave/floppy/Makefile.am | 8 +- tdeioslave/floppy/floppy.protocol | 2 +- tdeioslave/floppy/kio_floppy.cpp | 1169 ---------- tdeioslave/floppy/kio_floppy.h | 78 - tdeioslave/floppy/tdeio_floppy.cpp | 1169 ++++++++++ tdeioslave/floppy/tdeio_floppy.h | 78 + tdeioslave/home/CMakeLists.txt | 12 +- tdeioslave/home/Makefile.am | 10 +- tdeioslave/home/home.protocol | 2 +- tdeioslave/home/kdedmodule/homedirnotifymodule.cpp | 2 +- tdeioslave/home/kio_home.cpp | 186 -- tdeioslave/home/kio_home.h | 44 - tdeioslave/home/tdeio_home.cpp | 186 ++ tdeioslave/home/tdeio_home.h | 44 + tdeioslave/home/testhome.cpp | 2 +- tdeioslave/info/CMakeLists.txt | 4 +- tdeioslave/info/Makefile.am | 14 +- tdeioslave/info/info.cc | 12 +- tdeioslave/info/info.protocol | 2 +- tdeioslave/ldap/CMakeLists.txt | 6 +- tdeioslave/ldap/Makefile.am | 10 +- tdeioslave/ldap/kio_ldap.cpp | 1154 ---------- tdeioslave/ldap/kio_ldap.h | 65 - tdeioslave/ldap/ldap.protocol | 2 +- tdeioslave/ldap/ldaps.protocol | 2 +- tdeioslave/ldap/tdeio_ldap.cpp | 1154 ++++++++++ tdeioslave/ldap/tdeio_ldap.h | 65 + tdeioslave/mac/CMakeLists.txt | 6 +- tdeioslave/mac/ChangeLog | 2 +- tdeioslave/mac/Makefile.am | 12 +- tdeioslave/mac/README | 4 +- tdeioslave/mac/TODO | 2 +- tdeioslave/mac/kio_mac.cpp | 561 ----- tdeioslave/mac/kio_mac.h | 55 - tdeioslave/mac/mac.protocol | 2 +- tdeioslave/mac/tdeio_mac.cpp | 561 +++++ tdeioslave/mac/tdeio_mac.h | 55 + tdeioslave/man/CMakeLists.txt | 10 +- tdeioslave/man/Makefile.am | 24 +- tdeioslave/man/kio_man.cpp | 1533 ------------- tdeioslave/man/kio_man.css | 21 - tdeioslave/man/kio_man.h | 100 - tdeioslave/man/kio_man_test.cpp | 38 - tdeioslave/man/man.protocol | 2 +- tdeioslave/man/man2html.cpp | 2 +- tdeioslave/man/tdeio_man.cpp | 1533 +++++++++++++ tdeioslave/man/tdeio_man.css | 21 + tdeioslave/man/tdeio_man.h | 100 + tdeioslave/man/tdeio_man_test.cpp | 38 + tdeioslave/media/CMakeLists.txt | 12 +- tdeioslave/media/Makefile.am | 10 +- tdeioslave/media/kio_media.cpp | 276 --- tdeioslave/media/kio_media.h | 54 - tdeioslave/media/media.protocol | 2 +- tdeioslave/media/mediamanager/halbackend.cpp | 2 +- tdeioslave/media/mediamanager/mediamanager.cpp | 2 +- tdeioslave/media/mounthelper/CMakeLists.txt | 6 +- tdeioslave/media/mounthelper/Makefile.am | 8 +- .../media/mounthelper/kio_media_mounthelper.cpp | 282 --- .../media/mounthelper/kio_media_mounthelper.h | 57 - .../media/mounthelper/tdeio_media_mounthelper.cpp | 282 +++ .../media/mounthelper/tdeio_media_mounthelper.h | 57 + tdeioslave/media/services/media_decrypt.desktop | 2 +- tdeioslave/media/services/media_eject.desktop | 2 +- tdeioslave/media/services/media_mount.desktop | 2 +- .../media/services/media_safelyremove.desktop | 2 +- tdeioslave/media/services/media_unmount.desktop | 2 +- tdeioslave/media/tdecmodule/main.cpp | 2 +- .../media/tdefile-plugin/tdefilemediaplugin.cpp | 2 +- tdeioslave/media/tdeio_media.cpp | 276 +++ tdeioslave/media/tdeio_media.h | 54 + tdeioslave/media/testmedia.cpp | 2 +- tdeioslave/nfs/CMakeLists.txt | 6 +- tdeioslave/nfs/Makefile.am | 8 +- tdeioslave/nfs/kio_nfs.cpp | 1615 -------------- tdeioslave/nfs/kio_nfs.h | 109 - tdeioslave/nfs/nfs.protocol | 2 +- tdeioslave/nfs/tdeio_nfs.cpp | 1615 ++++++++++++++ tdeioslave/nfs/tdeio_nfs.h | 109 + tdeioslave/nntp/CMakeLists.txt | 4 +- tdeioslave/nntp/Makefile.am | 8 +- tdeioslave/nntp/nntp.cpp | 4 +- tdeioslave/nntp/nntp.protocol | 2 +- tdeioslave/nntp/nntps.protocol | 2 +- tdeioslave/pop3/CMakeLists.txt | 4 +- tdeioslave/pop3/Makefile.am | 8 +- tdeioslave/pop3/pop3.cc | 6 +- tdeioslave/pop3/pop3.protocol | 2 +- tdeioslave/pop3/pop3s.protocol | 2 +- tdeioslave/remote/CMakeLists.txt | 12 +- tdeioslave/remote/Makefile.am | 10 +- .../remote/kdedmodule/remotedirnotifymodule.cpp | 2 +- tdeioslave/remote/kio_remote.cpp | 234 -- tdeioslave/remote/kio_remote.h | 45 - tdeioslave/remote/remote.protocol | 2 +- tdeioslave/remote/tdeio_remote.cpp | 234 ++ tdeioslave/remote/tdeio_remote.h | 45 + tdeioslave/remote/testremote.cpp | 2 +- tdeioslave/settings/CMakeLists.txt | 6 +- tdeioslave/settings/Makefile.am | 10 +- tdeioslave/settings/applications.protocol | 2 +- tdeioslave/settings/kio_settings.cc | 298 --- tdeioslave/settings/kio_settings.h | 0 tdeioslave/settings/programs.protocol | 2 +- tdeioslave/settings/settings.protocol | 2 +- tdeioslave/settings/tdeio_settings.cc | 298 +++ tdeioslave/settings/tdeio_settings.h | 0 tdeioslave/sftp/CHANGELOG | 2 +- tdeioslave/sftp/CMakeLists.txt | 6 +- tdeioslave/sftp/Makefile.am | 10 +- tdeioslave/sftp/kio_sftp.cpp | 2282 -------------------- tdeioslave/sftp/kio_sftp.h | 149 -- tdeioslave/sftp/sftp.protocol | 2 +- tdeioslave/sftp/tdeio_sftp.cpp | 2282 ++++++++++++++++++++ tdeioslave/sftp/tdeio_sftp.h | 149 ++ tdeioslave/smb/CMakeLists.txt | 8 +- tdeioslave/smb/Makefile.am | 24 +- tdeioslave/smb/kio_smb.cpp | 77 - tdeioslave/smb/kio_smb.h | 301 --- tdeioslave/smb/kio_smb_auth.cpp | 207 -- tdeioslave/smb/kio_smb_browse.cpp | 476 ---- tdeioslave/smb/kio_smb_config.cpp | 66 - tdeioslave/smb/kio_smb_dir.cpp | 345 --- tdeioslave/smb/kio_smb_file.cpp | 279 --- tdeioslave/smb/kio_smb_internal.cpp | 135 -- tdeioslave/smb/kio_smb_internal.h | 118 - tdeioslave/smb/kio_smb_mount.cpp | 211 -- tdeioslave/smb/smb.protocol | 2 +- tdeioslave/smb/tdeio_smb.cpp | 77 + tdeioslave/smb/tdeio_smb.h | 301 +++ tdeioslave/smb/tdeio_smb_auth.cpp | 207 ++ tdeioslave/smb/tdeio_smb_browse.cpp | 476 ++++ tdeioslave/smb/tdeio_smb_config.cpp | 66 + tdeioslave/smb/tdeio_smb_dir.cpp | 345 +++ tdeioslave/smb/tdeio_smb_file.cpp | 279 +++ tdeioslave/smb/tdeio_smb_internal.cpp | 135 ++ tdeioslave/smb/tdeio_smb_internal.h | 118 + tdeioslave/smb/tdeio_smb_mount.cpp | 211 ++ tdeioslave/smtp/CMakeLists.txt | 4 +- tdeioslave/smtp/Makefile.am | 10 +- tdeioslave/smtp/capabilities.cc | 2 +- tdeioslave/smtp/capabilities.h | 2 +- tdeioslave/smtp/command.cc | 4 +- tdeioslave/smtp/command.h | 2 +- tdeioslave/smtp/interactivesmtpserver.cc | 2 +- tdeioslave/smtp/interactivesmtpserver.h | 2 +- tdeioslave/smtp/request.cc | 2 +- tdeioslave/smtp/request.h | 2 +- tdeioslave/smtp/response.cc | 2 +- tdeioslave/smtp/response.h | 2 +- tdeioslave/smtp/smtp.cc | 6 +- tdeioslave/smtp/smtp.protocol | 2 +- tdeioslave/smtp/smtps.protocol | 2 +- tdeioslave/smtp/transactionstate.cc | 2 +- tdeioslave/smtp/transactionstate.h | 2 +- tdeioslave/system/CMakeLists.txt | 12 +- tdeioslave/system/Makefile.am | 10 +- .../system/kdedmodule/systemdirnotify.desktop | 2 +- .../system/kdedmodule/systemdirnotifymodule.cpp | 2 +- tdeioslave/system/kio_system.cpp | 189 -- tdeioslave/system/kio_system.h | 45 - tdeioslave/system/system.protocol | 2 +- tdeioslave/system/tdeio_system.cpp | 189 ++ tdeioslave/system/tdeio_system.h | 45 + tdeioslave/system/testsystem.cpp | 2 +- tdeioslave/tar/CMakeLists.txt | 4 +- tdeioslave/tar/Makefile.am | 8 +- tdeioslave/tar/ar.protocol | 2 +- tdeioslave/tar/tar.cc | 4 +- tdeioslave/tar/tar.protocol | 2 +- tdeioslave/tar/zip.protocol | 2 +- tdeioslave/thumbnail/CMakeLists.txt | 4 +- tdeioslave/thumbnail/Makefile.am | 8 +- tdeioslave/thumbnail/thumbnail.cpp | 6 +- tdeioslave/thumbnail/thumbnail.protocol | 2 +- tdeioslave/trash/CMakeLists.txt | 6 +- tdeioslave/trash/DESIGN | 8 +- tdeioslave/trash/Makefile.am | 8 +- tdeioslave/trash/kio_trash.cpp | 596 ----- tdeioslave/trash/kio_trash.h | 71 - tdeioslave/trash/ktrash.cpp | 2 +- tdeioslave/trash/tdefile-plugin/tdefile_trash.cpp | 2 +- tdeioslave/trash/tdeio_trash.cpp | 596 +++++ tdeioslave/trash/tdeio_trash.h | 71 + tdeioslave/trash/testtrash.cpp | 2 +- tdeioslave/trash/trash.protocol | 2 +- tdeioslave/trash/trashimpl.cpp | 10 +- tdeioslave/trash/trashimpl.h | 2 +- 228 files changed, 14543 insertions(+), 14543 deletions(-) delete mode 100644 tdeioslave/about/kio_about.cpp delete mode 100644 tdeioslave/about/kio_about.h create mode 100644 tdeioslave/about/tdeio_about.cpp create mode 100644 tdeioslave/about/tdeio_about.h delete mode 100644 tdeioslave/finger/kio_finger.cpp delete mode 100644 tdeioslave/finger/kio_finger.css delete mode 100644 tdeioslave/finger/kio_finger.h delete mode 100644 tdeioslave/finger/kio_finger.pl create mode 100644 tdeioslave/finger/tdeio_finger.cpp create mode 100644 tdeioslave/finger/tdeio_finger.css create mode 100644 tdeioslave/finger/tdeio_finger.h create mode 100644 tdeioslave/finger/tdeio_finger.pl delete mode 100644 tdeioslave/floppy/kio_floppy.cpp delete mode 100644 tdeioslave/floppy/kio_floppy.h create mode 100644 tdeioslave/floppy/tdeio_floppy.cpp create mode 100644 tdeioslave/floppy/tdeio_floppy.h delete mode 100644 tdeioslave/home/kio_home.cpp delete mode 100644 tdeioslave/home/kio_home.h create mode 100644 tdeioslave/home/tdeio_home.cpp create mode 100644 tdeioslave/home/tdeio_home.h delete mode 100644 tdeioslave/ldap/kio_ldap.cpp delete mode 100644 tdeioslave/ldap/kio_ldap.h create mode 100644 tdeioslave/ldap/tdeio_ldap.cpp create mode 100644 tdeioslave/ldap/tdeio_ldap.h delete mode 100644 tdeioslave/mac/kio_mac.cpp delete mode 100644 tdeioslave/mac/kio_mac.h create mode 100644 tdeioslave/mac/tdeio_mac.cpp create mode 100644 tdeioslave/mac/tdeio_mac.h delete mode 100644 tdeioslave/man/kio_man.cpp delete mode 100644 tdeioslave/man/kio_man.css delete mode 100644 tdeioslave/man/kio_man.h delete mode 100644 tdeioslave/man/kio_man_test.cpp create mode 100644 tdeioslave/man/tdeio_man.cpp create mode 100644 tdeioslave/man/tdeio_man.css create mode 100644 tdeioslave/man/tdeio_man.h create mode 100644 tdeioslave/man/tdeio_man_test.cpp delete mode 100644 tdeioslave/media/kio_media.cpp delete mode 100644 tdeioslave/media/kio_media.h delete mode 100644 tdeioslave/media/mounthelper/kio_media_mounthelper.cpp delete mode 100644 tdeioslave/media/mounthelper/kio_media_mounthelper.h create mode 100644 tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp create mode 100644 tdeioslave/media/mounthelper/tdeio_media_mounthelper.h create mode 100644 tdeioslave/media/tdeio_media.cpp create mode 100644 tdeioslave/media/tdeio_media.h delete mode 100644 tdeioslave/nfs/kio_nfs.cpp delete mode 100644 tdeioslave/nfs/kio_nfs.h create mode 100644 tdeioslave/nfs/tdeio_nfs.cpp create mode 100644 tdeioslave/nfs/tdeio_nfs.h delete mode 100644 tdeioslave/remote/kio_remote.cpp delete mode 100644 tdeioslave/remote/kio_remote.h create mode 100644 tdeioslave/remote/tdeio_remote.cpp create mode 100644 tdeioslave/remote/tdeio_remote.h delete mode 100644 tdeioslave/settings/kio_settings.cc delete mode 100644 tdeioslave/settings/kio_settings.h create mode 100644 tdeioslave/settings/tdeio_settings.cc create mode 100644 tdeioslave/settings/tdeio_settings.h delete mode 100644 tdeioslave/sftp/kio_sftp.cpp delete mode 100644 tdeioslave/sftp/kio_sftp.h create mode 100644 tdeioslave/sftp/tdeio_sftp.cpp create mode 100644 tdeioslave/sftp/tdeio_sftp.h delete mode 100644 tdeioslave/smb/kio_smb.cpp delete mode 100644 tdeioslave/smb/kio_smb.h delete mode 100644 tdeioslave/smb/kio_smb_auth.cpp delete mode 100644 tdeioslave/smb/kio_smb_browse.cpp delete mode 100644 tdeioslave/smb/kio_smb_config.cpp delete mode 100644 tdeioslave/smb/kio_smb_dir.cpp delete mode 100644 tdeioslave/smb/kio_smb_file.cpp delete mode 100644 tdeioslave/smb/kio_smb_internal.cpp delete mode 100644 tdeioslave/smb/kio_smb_internal.h delete mode 100644 tdeioslave/smb/kio_smb_mount.cpp create mode 100644 tdeioslave/smb/tdeio_smb.cpp create mode 100644 tdeioslave/smb/tdeio_smb.h create mode 100644 tdeioslave/smb/tdeio_smb_auth.cpp create mode 100644 tdeioslave/smb/tdeio_smb_browse.cpp create mode 100644 tdeioslave/smb/tdeio_smb_config.cpp create mode 100644 tdeioslave/smb/tdeio_smb_dir.cpp create mode 100644 tdeioslave/smb/tdeio_smb_file.cpp create mode 100644 tdeioslave/smb/tdeio_smb_internal.cpp create mode 100644 tdeioslave/smb/tdeio_smb_internal.h create mode 100644 tdeioslave/smb/tdeio_smb_mount.cpp delete mode 100644 tdeioslave/system/kio_system.cpp delete mode 100644 tdeioslave/system/kio_system.h create mode 100644 tdeioslave/system/tdeio_system.cpp create mode 100644 tdeioslave/system/tdeio_system.h delete mode 100644 tdeioslave/trash/kio_trash.cpp delete mode 100644 tdeioslave/trash/kio_trash.h create mode 100644 tdeioslave/trash/tdeio_trash.cpp create mode 100644 tdeioslave/trash/tdeio_trash.h (limited to 'tdeioslave') diff --git a/tdeioslave/DEBUG.howto b/tdeioslave/DEBUG.howto index 6218f2fba..813df102d 100644 --- a/tdeioslave/DEBUG.howto +++ b/tdeioslave/DEBUG.howto @@ -74,7 +74,7 @@ $TDEDIR/share/config/kdebugrc. InfoOutput=0 InfoFilename=/tmp/http -This redirects all debug info for areas 7103 and 7113 (as used by kio_http) +This redirects all debug info for areas 7103 and 7113 (as used by tdeio_http) to the file /tmp/http. To get debug information from the SMB slave you can add the following to diff --git a/tdeioslave/DESIGN b/tdeioslave/DESIGN index 9b62f3c34..01a0da1f6 100644 --- a/tdeioslave/DESIGN +++ b/tdeioslave/DESIGN @@ -10,7 +10,7 @@ Well, that's nice. How do they work? To understand it, you'll need two ice cubes, a pair of handcuffs, and a ferret. Some Crisco (or other shortening) is optional. Well, that aside, -this document focuses on the business end of the whole kio library. The +this document focuses on the business end of the whole tdeio library. The ioslave. See the documentation of the SlaveBase class for the methods you need to reimplement, and see http://developer.kde.org/documentation/design/kde/ioslaves/ for more docu diff --git a/tdeioslave/about/CMakeLists.txt b/tdeioslave/about/CMakeLists.txt index aaa2a5aff..ef7073ed1 100644 --- a/tdeioslave/about/CMakeLists.txt +++ b/tdeioslave/about/CMakeLists.txt @@ -25,12 +25,12 @@ link_directories( install( FILES about.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_about (module) ######################## +##### tdeio_about (module) ######################## -set( target kio_about ) +set( target tdeio_about ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_about.cpp + SOURCES tdeio_about.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/about/Makefile.am b/tdeioslave/about/Makefile.am index 18bffeeec..7ac082ee3 100644 --- a/tdeioslave/about/Makefile.am +++ b/tdeioslave/about/Makefile.am @@ -5,12 +5,12 @@ AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB ####### Files -kde_module_LTLIBRARIES = kio_about.la +kde_module_LTLIBRARIES = tdeio_about.la -kio_about_la_SOURCES = kio_about.cpp -kio_about_la_LIBADD = $(LIB_KSYCOCA) -kio_about_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_about.h +tdeio_about_la_SOURCES = tdeio_about.cpp +tdeio_about_la_LIBADD = $(LIB_KSYCOCA) +tdeio_about_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +noinst_HEADERS = tdeio_about.h kdelnk_DATA = about.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/about/about.protocol b/tdeioslave/about/about.protocol index bc685bfe5..ae6172561 100644 --- a/tdeioslave/about/about.protocol +++ b/tdeioslave/about/about.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_about +exec=tdeio_about protocol=about input=none output=filesystem diff --git a/tdeioslave/about/kio_about.cpp b/tdeioslave/about/kio_about.cpp deleted file mode 100644 index 29fba8e4a..000000000 --- a/tdeioslave/about/kio_about.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2002 John Firebaugh - - 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_about.h" - -#include -#include -#include -#include - -using namespace TDEIO; - -AboutProtocol::AboutProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : SlaveBase("about", pool_socket, app_socket) -{ -} - -AboutProtocol::~AboutProtocol() -{ -} - -void AboutProtocol::get( const KURL& ) -{ - TQByteArray output; - - TQTextStream os( output, IO_WriteOnly ); - os.setEncoding( TQTextStream::Latin1 ); // In fast ASCII - - os << "about:blank"; - - data( output ); - finished(); -} - -void AboutProtocol::mimetype( const KURL& ) -{ - mimeType("text/html"); - finished(); -} - -extern "C" -{ - int KDE_EXPORT kdemain( int argc, char **argv ) { - - TDEInstance instance("kio_about"); - - if (argc != 4) - { - fprintf(stderr, "Usage: kio_about protocol domain-socket1 domain-socket2\n"); - exit(-1); - } - - AboutProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - return 0; - } -} - diff --git a/tdeioslave/about/kio_about.h b/tdeioslave/about/kio_about.h deleted file mode 100644 index eacaf09dc..000000000 --- a/tdeioslave/about/kio_about.h +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2002 John Firebaugh - - 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_about_h__ -#define __kio_about_h__ - -#include - -#include -#include - - -class AboutProtocol : public TDEIO::SlaveBase -{ -public: - AboutProtocol(const TQCString &pool_socket, const TQCString &app_socket); - virtual ~AboutProtocol(); - - virtual void get(const KURL& url); - virtual void mimetype(const KURL& url); -}; - -#endif diff --git a/tdeioslave/about/tdeio_about.cpp b/tdeioslave/about/tdeio_about.cpp new file mode 100644 index 000000000..f8ac109f3 --- /dev/null +++ b/tdeioslave/about/tdeio_about.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE libraries + + Copyright (c) 2002 John Firebaugh + + 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 "tdeio_about.h" + +#include +#include +#include +#include + +using namespace TDEIO; + +AboutProtocol::AboutProtocol(const TQCString &pool_socket, const TQCString &app_socket) + : SlaveBase("about", pool_socket, app_socket) +{ +} + +AboutProtocol::~AboutProtocol() +{ +} + +void AboutProtocol::get( const KURL& ) +{ + TQByteArray output; + + TQTextStream os( output, IO_WriteOnly ); + os.setEncoding( TQTextStream::Latin1 ); // In fast ASCII + + os << "about:blank"; + + data( output ); + finished(); +} + +void AboutProtocol::mimetype( const KURL& ) +{ + mimeType("text/html"); + finished(); +} + +extern "C" +{ + int KDE_EXPORT kdemain( int argc, char **argv ) { + + TDEInstance instance("tdeio_about"); + + if (argc != 4) + { + fprintf(stderr, "Usage: tdeio_about protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + + AboutProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + + return 0; + } +} + diff --git a/tdeioslave/about/tdeio_about.h b/tdeioslave/about/tdeio_about.h new file mode 100644 index 000000000..9d8eedc79 --- /dev/null +++ b/tdeioslave/about/tdeio_about.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE libraries + + Copyright (c) 2002 John Firebaugh + + 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 __tdeio_about_h__ +#define __tdeio_about_h__ + +#include + +#include +#include + + +class AboutProtocol : public TDEIO::SlaveBase +{ +public: + AboutProtocol(const TQCString &pool_socket, const TQCString &app_socket); + virtual ~AboutProtocol(); + + virtual void get(const KURL& url); + virtual void mimetype(const KURL& url); +}; + +#endif diff --git a/tdeioslave/cgi/CMakeLists.txt b/tdeioslave/cgi/CMakeLists.txt index 87923f86c..130aa9a1e 100644 --- a/tdeioslave/cgi/CMakeLists.txt +++ b/tdeioslave/cgi/CMakeLists.txt @@ -28,9 +28,9 @@ link_directories( install( FILES cgi.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_cgi (module) ########################## +##### tdeio_cgi (module) ########################## -set( target kio_cgi ) +set( target tdeio_cgi ) tde_add_kpart( ${target} AUTOMOC SOURCES cgi.cpp diff --git a/tdeioslave/cgi/Makefile.am b/tdeioslave/cgi/Makefile.am index cc71753e9..b996757cf 100644 --- a/tdeioslave/cgi/Makefile.am +++ b/tdeioslave/cgi/Makefile.am @@ -2,11 +2,11 @@ SUBDIRS = kcmcgi INCLUDES = $(all_includes) -kde_module_LTLIBRARIES = kio_cgi.la +kde_module_LTLIBRARIES = tdeio_cgi.la -kio_cgi_la_SOURCES = cgi.cpp -kio_cgi_la_LIBADD = $(LIB_KIO) -kio_cgi_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_cgi_la_SOURCES = cgi.cpp +tdeio_cgi_la_LIBADD = $(LIB_KIO) +tdeio_cgi_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = cgi.h diff --git a/tdeioslave/cgi/cgi.cpp b/tdeioslave/cgi/cgi.cpp index 317b1610a..e0e03e454 100644 --- a/tdeioslave/cgi/cgi.cpp +++ b/tdeioslave/cgi/cgi.cpp @@ -257,13 +257,13 @@ extern "C" { int KDE_EXPORT kdemain( int argc, char **argv ); } int kdemain( int argc, char **argv ) { - TDEInstance instance( "kio_cgi" ); + TDEInstance instance( "tdeio_cgi" ); - kdDebug(7124) << "kio_cgi starting " << getpid() << endl; + kdDebug(7124) << "tdeio_cgi starting " << getpid() << endl; if (argc != 4) { - fprintf(stderr, "Usage: kio_cgi protocol domain-socket1 domain-socket2\n"); + fprintf(stderr, "Usage: tdeio_cgi protocol domain-socket1 domain-socket2\n"); exit(-1); } diff --git a/tdeioslave/cgi/cgi.protocol b/tdeioslave/cgi/cgi.protocol index eb6c45217..24910f731 100644 --- a/tdeioslave/cgi/cgi.protocol +++ b/tdeioslave/cgi/cgi.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_cgi +exec=tdeio_cgi protocol=cgi input=none output=filesystem diff --git a/tdeioslave/configure.in.in b/tdeioslave/configure.in.in index 331a300b8..27632c31a 100644 --- a/tdeioslave/configure.in.in +++ b/tdeioslave/configure.in.in @@ -3,7 +3,7 @@ KDE_CHECK_SSL sasl2_header="no" SASL2_LIBS="" -KDE_CHECK_HEADERS(sasl.h)dnl SASL1 header is enough for kio_ldap +KDE_CHECK_HEADERS(sasl.h)dnl SASL1 header is enough for tdeio_ldap KDE_CHECK_HEADERS(sasl/sasl.h, sasl2_header="yes") if test "$sasl2_header" = "yes" ; then KDE_CHECK_LIB(sasl2, sasl_client_init, SASL2_LIBS="-lsasl2") diff --git a/tdeioslave/filter/CMakeLists.txt b/tdeioslave/filter/CMakeLists.txt index 4b0c3d36c..587a89fb6 100644 --- a/tdeioslave/filter/CMakeLists.txt +++ b/tdeioslave/filter/CMakeLists.txt @@ -25,9 +25,9 @@ link_directories( install( FILES gzip.protocol bzip.protocol bzip2.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_filter (module) ####################### +##### tdeio_filter (module) ####################### -set( target kio_filter ) +set( target tdeio_filter ) tde_add_kpart( ${target} AUTOMOC SOURCES filter.cc diff --git a/tdeioslave/filter/Makefile.am b/tdeioslave/filter/Makefile.am index f315064c8..d4e58d7f8 100644 --- a/tdeioslave/filter/Makefile.am +++ b/tdeioslave/filter/Makefile.am @@ -2,11 +2,11 @@ KDE_CPPFLAGS = -DQT_NO_CAST_ASCII INCLUDES = $(all_includes) -kde_module_LTLIBRARIES = kio_filter.la +kde_module_LTLIBRARIES = tdeio_filter.la -kio_filter_la_SOURCES = filter.cc -kio_filter_la_LIBADD = $(LIB_KSYCOCA) -kio_filter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_filter_la_SOURCES = filter.cc +tdeio_filter_la_LIBADD = $(LIB_KSYCOCA) +tdeio_filter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = filter.h METASOURCES = AUTO diff --git a/tdeioslave/filter/bzip.protocol b/tdeioslave/filter/bzip.protocol index 4d729f5ea..46d74ca33 100644 --- a/tdeioslave/filter/bzip.protocol +++ b/tdeioslave/filter/bzip.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_filter +exec=tdeio_filter protocol=bzip mimetype=application/x-bzip input=stream diff --git a/tdeioslave/filter/bzip2.protocol b/tdeioslave/filter/bzip2.protocol index c2b8d2c51..7d0d66fcf 100644 --- a/tdeioslave/filter/bzip2.protocol +++ b/tdeioslave/filter/bzip2.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_filter +exec=tdeio_filter protocol=bzip2 mimetype=application/x-bzip2 input=stream diff --git a/tdeioslave/filter/filter.cc b/tdeioslave/filter/filter.cc index 793921c6c..a429103e1 100644 --- a/tdeioslave/filter/filter.cc +++ b/tdeioslave/filter/filter.cc @@ -36,13 +36,13 @@ extern "C" { KDE_EXPORT int kdemain(int argc, char **argv); } int kdemain( int argc, char ** argv) { - TDEInstance instance( "kio_filter" ); + TDEInstance instance( "tdeio_filter" ); kdDebug(7110) << "Starting " << getpid() << endl; if (argc != 4) { - fprintf(stderr, "Usage: kio_filter protocol domain-socket1 domain-socket2\n"); + fprintf(stderr, "Usage: tdeio_filter protocol domain-socket1 domain-socket2\n"); exit(-1); } diff --git a/tdeioslave/filter/gzip.protocol b/tdeioslave/filter/gzip.protocol index f0f57911c..01aee5b5d 100644 --- a/tdeioslave/filter/gzip.protocol +++ b/tdeioslave/filter/gzip.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_filter +exec=tdeio_filter protocol=gzip mimetype=application/gzip input=stream diff --git a/tdeioslave/finger/CMakeLists.txt b/tdeioslave/finger/CMakeLists.txt index 096b483d0..65088aaf4 100644 --- a/tdeioslave/finger/CMakeLists.txt +++ b/tdeioslave/finger/CMakeLists.txt @@ -23,15 +23,15 @@ link_directories( ##### other data ################################ install( FILES finger.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -install( FILES kio_finger.pl kio_finger.css DESTINATION ${DATA_INSTALL_DIR}/tdeio_finger ) +install( FILES tdeio_finger.pl tdeio_finger.css DESTINATION ${DATA_INSTALL_DIR}/tdeio_finger ) -##### kio_finger (module) ####################### +##### tdeio_finger (module) ####################### -set( target kio_finger ) +set( target tdeio_finger ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_finger.cpp + SOURCES tdeio_finger.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/finger/Makefile.am b/tdeioslave/finger/Makefile.am index 9c2792df3..46e0ff69c 100644 --- a/tdeioslave/finger/Makefile.am +++ b/tdeioslave/finger/Makefile.am @@ -1,4 +1,4 @@ -## Makfile.am for kio_finger +## Makfile.am for tdeio_finger ## Edit from Makefile.am of tdebase/tdeioslave/man INCLUDES= $(all_includes) @@ -6,20 +6,20 @@ AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB ####### Files -kde_module_LTLIBRARIES = kio_finger.la +kde_module_LTLIBRARIES = tdeio_finger.la -kio_finger_la_SOURCES = kio_finger.cpp -kio_finger_la_LIBADD = -lkio -kio_finger_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_finger_la_SOURCES = tdeio_finger.cpp +tdeio_finger_la_LIBADD = -ltdeio +tdeio_finger_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_finger.h +noinst_HEADERS = tdeio_finger.h kdelnk_DATA = finger.protocol kdelnkdir = $(kde_servicesdir) -kio_finger_data_DATA = kio_finger.pl kio_finger.css -kio_finger_datadir = $(kde_datadir)/tdeio_finger -EXTRA_DIST=$(kio_finger_data_DATA) +tdeio_finger_data_DATA = tdeio_finger.pl tdeio_finger.css +tdeio_finger_datadir = $(kde_datadir)/tdeio_finger +EXTRA_DIST=$(tdeio_finger_data_DATA) METASOURCES = AUTO diff --git a/tdeioslave/finger/finger.protocol b/tdeioslave/finger/finger.protocol index 8e2cdc80f..59bfec017 100644 --- a/tdeioslave/finger/finger.protocol +++ b/tdeioslave/finger/finger.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_finger +exec=tdeio_finger protocol=finger input=none output=stream diff --git a/tdeioslave/finger/kio_finger.cpp b/tdeioslave/finger/kio_finger.cpp deleted file mode 100644 index b223e1024..000000000 --- a/tdeioslave/finger/kio_finger.cpp +++ /dev/null @@ -1,266 +0,0 @@ - -/*************************************************************************** - kio_finger.cpp - description - ------------------- - begin : Sun Aug 12 2000 - copyright : (C) 2000 by Andreas Schlapbach - email : schlpbch@iam.unibe.ch - ***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "kio_finger.h" - - -using namespace TDEIO; - -static const TQString defaultRefreshRate = "60"; - -extern "C" -{ - KDE_EXPORT int kdemain( int argc, char **argv ) - { - TDEInstance instance( "kio_finger" ); - - //kdDebug() << "*** Starting kio_finger " << getpid() << endl; - - if (argc != 4) - { - fprintf(stderr, "Usage: kio_finger protocol domain-socket1 domain-socket2\n"); - exit(-1); - } - - FingerProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - //kdDebug() << "*** kio_finger Done" << endl; - return 0; - } -} - - -/* ---------------------------------------------------------------------------------- */ - - -FingerProtocol::FingerProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : TQObject(), SlaveBase("finger", pool_socket, app_socket) -{ - myStdStream = new TQString(); - getProgramPath(); -} - - -/* ---------------------------------------------------------------------------------- */ - - -FingerProtocol::~FingerProtocol() -{ - //kdDebug() << "FingerProtocol::~FingerProtocol()" << endl; - delete myURL; - delete myPerlPath; - delete myFingerPath; - delete myFingerPerlScript; - delete myFingerCSSFile; - delete myStdStream; -} - - -/* ---------------------------------------------------------------------------------- */ - - -void FingerProtocol::get(const KURL& url ) -{ - //kdDebug() << "kio_finger::get(const KURL& url)" << endl ; - - this->parseCommandLine(url); - - //kdDebug() << "myURL: " << myURL->prettyURL() << endl; - - // Reset the stream - *myStdStream=""; - - TQString query = myURL->query(); - TQString refreshRate = defaultRefreshRate; - - //kdDebug() << "query: " << query << endl; - - // Check the validity of the query - - TQRegExp regExp("?refreshRate=[0-9][0-9]*", true, true); - if (query.contains(regExp)) { - //kdDebug() << "looks like a valid query" << endl; - TQRegExp regExp( "([0-9]+)" ); - regExp.search(query); - refreshRate = regExp.cap(0); - } - - //kdDebug() << "Refresh rate: " << refreshRate << endl; - - myTDEProcess = new TDEProcess(); - *myTDEProcess << *myPerlPath << *myFingerPerlScript - << *myFingerPath << *myFingerCSSFile - << refreshRate << myURL->host() << myURL->user() ; - - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - //connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - // this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - data(TQCString(TQString(*myStdStream).local8Bit())); - - data(TQByteArray()); - finished(); - - //clean up - - delete myTDEProcess; -} - - -/* ---------------------------------------------------------------------------------- */ - - -void FingerProtocol::slotGetStdOutput(TDEProcess* /* p */, char *s, int len) -{ - //kdDebug() << "void FingerProtocol::slotGetStdoutOutput()" << endl; - *myStdStream += TQString::fromLocal8Bit(s, len); -} - - -/* ---------------------------------------------------------------------------------- */ - - -void FingerProtocol::mimetype(const KURL & /*url*/) -{ - mimeType("text/html"); - finished(); -} - - -/* ---------------------------------------------------------------------------------- */ - - -void FingerProtocol::getProgramPath() -{ - //kdDebug() << "kfingerMainWindow::getProgramPath()" << endl; - // Not to sure wether I'm using the right error number here. - schlpbch - - - myPerlPath = new TQString(TDEGlobal::dirs()->findExe("perl")); - if (myPerlPath->isEmpty()) - { - //kdDebug() << "Perl command not found" << endl; - this->error(ERR_CANNOT_LAUNCH_PROCESS, - i18n("Could not find the Perl program on your system, please install.")); - exit(); - } - else - { - //kdDebug() << "Perl command found:" << *myPerlPath << endl; - } - - myFingerPath = new TQString(TDEGlobal::dirs()->findExe("finger")); - if ((myFingerPath->isEmpty())) - { - //kdDebug() << "Finger command not found" << endl; - this->error(ERR_CANNOT_LAUNCH_PROCESS, - i18n("Could not find the Finger program on your system, please install.")); - exit(); - } - else - { - //kdDebug() << "Finger command found:" << *myFingerPath << endl; - } - - myFingerPerlScript = new TQString(locate("data","kio_finger/tdeio_finger.pl")); - if (myFingerPerlScript->isEmpty()) - { - //kdDebug() << "kio_finger.pl script not found" << endl; - this->error(ERR_CANNOT_LAUNCH_PROCESS, - i18n("kio_finger Perl script not found.")); - exit(); - } - else - { - //kdDebug() << "kio_finger perl script found: " << *myFingerPerlScript << endl; - } - - myFingerCSSFile = new TQString(locate("data","kio_finger/tdeio_finger.css")); - if (myFingerCSSFile->isEmpty()) - { - //kdDebug() << "kio_finger.css file not found" << endl; - this->warning(i18n("kio_finger CSS script not found. Output will look ugly.")); - } - else - { - //kdDebug() << "kio_finger CSS file found: " << *myFingerCSSFile << endl; - } -} - - -/* --------------------------------------------------------------------------- */ - - -void FingerProtocol::parseCommandLine(const KURL& url) -{ - myURL = new KURL(url); - - /* - * Generate a valid finger url - */ - - if(myURL->isEmpty() || !myURL->isValid() || - (myURL->user().isEmpty() && myURL->host().isEmpty())) - { - myURL->setProtocol("finger"); - myURL->setUser(""); - myURL->setHost("localhost"); - } - - /* - * If no specific port is specified, set it to 79. - */ - - if(myURL->port() == 0) { - myURL->setPort(79); - } - - /* - * If no refresh rate is given, set it to defaultRefreshRate - */ - - if (myURL->query().isEmpty()) { - myURL->setQuery("?refreshRate="+defaultRefreshRate); - } -} - -/* ---------------------------------------------------------------------------------- */ -#include "kio_finger.moc" -/* ---------------------------------------------------------------------------------- */ - diff --git a/tdeioslave/finger/kio_finger.css b/tdeioslave/finger/kio_finger.css deleted file mode 100644 index 06deb81aa..000000000 --- a/tdeioslave/finger/kio_finger.css +++ /dev/null @@ -1,69 +0,0 @@ -BODY { - color: #FFFFCC; - background-color: #000000; - padding: 2em; - margin: auto; -} - -A:link {color: #82A7D0} -A:visited {color: #999999} -A:active {color: #999999} - -H1 { - color: #999999; - background-color: #000000; - font: 200% Helvetica, sans-serif; - font-variant: normal; - padding: 1em; - margin: auto; -} - -.mainTable { - background-color: #000000; - border: thin solid; - margin: auto; -} - - -.courierText { - color: #FFFFCC; - background-color: #000000; - font: 120% Courier, sans-serif; - font-variant: normal; - text-align: left; - padding: 0em; -} - -.commandText { - color: #FFFFCC; - background-color: #000000; - font: 120% Courier, sans-serif; - font-variant: normal; - text-align: center; - padding: 0.5em; -} - -.niceText { - color: #009999; - background-color: #000000; - font: 120% Arial, sans-serif; - font-variant: normal; - text-align: center; - padding: 0.5em; -} - -.finger { color: #82A7D0} -.domainName { color: #D0A000} -.ipNumber { color: #D0A000} -.os { color: #82A7D0} -.username { color: #82A7D0} -.directory { color: #D0A000} -.shell { color: #D0A000} -.notLoggedIn { color: #00A000} -.loggedIn { color: #B00000} -.newMail { color: #82A7D0} -.plan { color: #D0A000} -.noNewMail { color: #BB0000} -.noPlan { color: #BB0000} - - diff --git a/tdeioslave/finger/kio_finger.h b/tdeioslave/finger/kio_finger.h deleted file mode 100644 index eac8ad291..000000000 --- a/tdeioslave/finger/kio_finger.h +++ /dev/null @@ -1,64 +0,0 @@ - -/*************************************************************************** - kio_finger.h - description - ------------------- - begin : Sun Aug 12 2000 - copyright : (C) 2000 by Andreas Schlapbach - email : schlpbch@iam.unibe.ch - ***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - - -#ifndef __kio_finger_h__ -#define __kio_finger_h__ - -#include -#include - -#include -#include -#include -#include - -class FingerProtocol : public TQObject, public TDEIO::SlaveBase -{ - Q_OBJECT - -public: - - FingerProtocol(const TQCString &pool_socket, const TQCString &app_socket); - virtual ~FingerProtocol(); - - virtual void mimetype(const KURL& url); - virtual void get(const KURL& url); - -private slots: - void slotGetStdOutput(TDEProcess*, char*, int); - -private: - KURL *myURL; - - QString *myPerlPath; - TQString *myFingerPath; - TQString *myFingerPerlScript; - TQString *myFingerCSSFile; - - QString *myStdStream; - - - TDEProcess *myTDEProcess; - - void getProgramPath(); - void parseCommandLine(const KURL& url); -}; - - -#endif diff --git a/tdeioslave/finger/kio_finger.pl b/tdeioslave/finger/kio_finger.pl deleted file mode 100644 index 8965ea523..000000000 --- a/tdeioslave/finger/kio_finger.pl +++ /dev/null @@ -1,175 +0,0 @@ -##!/usr/bin/perl -# -# Copyright Andreas Schlapbach, schlpbch@iam.unibe.ch, 2001 -# http://iamexwiwww.unibe.ch/studenten/kfinger -# -# Touch at your own risk. - - -# Highlight mail addresses or url - -$mails = '/>/g; - -$USER =~ s/&/&/g; -$USER =~ s//>/g; - -# HTML Header - -print < - - - - finger $USER\@$HOST - - - - - - - - - \n"; - -# Finger-Talk options - -if ($USER) # is $USER nil ? -{ -print < - - - -UserQuery -} -else -{ -print < -
-

finger $USER\@$HOST

-
- -HTMLHeader - -# Run finger command and save it into a buffer - -open(F, "-|") || exec $FINGERCMD, "$USER\@$HOST"; -@lines = ; -close(F); - -# Do highlighting using perl regular expressions on every line received. -# Order is important here. - -foreach $output (@lines) - { - $output =~ s/((\w)+\@((\w)+(.))*(\w)+)/$mails$1$urlspace$1$urlend/gi; # Highlight email address - $output =~ s/((http|ftp)(:\/\/)(\S)+)/$urls$1$urlspace$1$urlend/gi; # Highlight urls - $output =~ s/((\d)+\.(\d)+\.(\d)+\.(\d)+)/$ipNumber$1$close/gi; # Highlight IP number - $output =~ s/((\w)+\.(\w)+\.(\w|-)+\s)/$domainName$1$close/gi; # Highlight domain name (\s is important) - $output =~ s/(finger:)/$finger$1$close/gim; # Highlight finger - $output =~ s/(Linux)/$os$1$close/gim; # Highlight Linux - if ($USER) # is $USER nil ? - { - $output =~ s/^Login:\s*(\w*)/Login: $mails$1\@$HOST$urlspace$1$urlend/gi; - $output =~ s/^Login Name:\s*(\w*)/Login Name:$mails$1\@$HOST$urlspace$1$urlend/gi; - $output =~ s/Name:(((\s*)(\w+))+\n)/Name:$username$1$close\n/gi; # Linux - $output =~ s/In real life:(((\s*)(\w+))+\n)/In real life:$username$1$close\n/gi; # Solaris - $output =~ s/^Directory:((\s*)(\/(\w)+)+)/Directory:$directory$1$close/gi; # Highlight Directory - $output =~ s/Shell:((\s*)(\/(\w)+)+)/Shell:$shell$1$close/gi; # Highlight Shell - $output =~ s/(not presently logged)/$notLoggedIn$1$close/gi; - $output =~ s/con (\w*)/con $loggedIn$1$close/gi; - $output =~ s/^(New mail)/$newMail$1$close/gi; - $output =~ s/^(No mail.)/$noNewMail$1$close/gim; - $output =~ s/^(Plan:)/$plan$1$close/gi; - $output =~ s/^(No plan.)/$noPlan$1$close/gim; - } - else - { - $output =~ s/^(\w+)/$mails$1\@$HOST$urlspace$1$urlend/m unless ($output =~ m/$keywordlist/m); - } - # line consists of white space only? - if ($output =~ m/\S/gi) - { - print " \n"; - } - else - { - print " \n"; - } -} - -print "
$output
  
\n"; -print "
- finger -
-HostQueryHead - - @lines = split /^/m, $buffer; - foreach $output2 (@lines) - { - if ($output2 =~ m/^(\w+)/gi and not ($output2 =~ m/$keywordlist/m)) - { - $USER = $&; - print " \n"; - # - talk\n\n"; - } - else - { - print " \n"; - } - } - -print < - - -HostQueryTail -} - -# HTMLTail - -print < - - -
finger\n
  
refresh rate: $REFRESHRATE seconds.
- - -HTMLTail diff --git a/tdeioslave/finger/tdeio_finger.cpp b/tdeioslave/finger/tdeio_finger.cpp new file mode 100644 index 000000000..ba0294918 --- /dev/null +++ b/tdeioslave/finger/tdeio_finger.cpp @@ -0,0 +1,266 @@ + +/*************************************************************************** + tdeio_finger.cpp - description + ------------------- + begin : Sun Aug 12 2000 + copyright : (C) 2000 by Andreas Schlapbach + email : schlpbch@iam.unibe.ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "tdeio_finger.h" + + +using namespace TDEIO; + +static const TQString defaultRefreshRate = "60"; + +extern "C" +{ + KDE_EXPORT int kdemain( int argc, char **argv ) + { + TDEInstance instance( "tdeio_finger" ); + + //kdDebug() << "*** Starting tdeio_finger " << getpid() << endl; + + if (argc != 4) + { + fprintf(stderr, "Usage: tdeio_finger protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + + FingerProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + + //kdDebug() << "*** tdeio_finger Done" << endl; + return 0; + } +} + + +/* ---------------------------------------------------------------------------------- */ + + +FingerProtocol::FingerProtocol(const TQCString &pool_socket, const TQCString &app_socket) + : TQObject(), SlaveBase("finger", pool_socket, app_socket) +{ + myStdStream = new TQString(); + getProgramPath(); +} + + +/* ---------------------------------------------------------------------------------- */ + + +FingerProtocol::~FingerProtocol() +{ + //kdDebug() << "FingerProtocol::~FingerProtocol()" << endl; + delete myURL; + delete myPerlPath; + delete myFingerPath; + delete myFingerPerlScript; + delete myFingerCSSFile; + delete myStdStream; +} + + +/* ---------------------------------------------------------------------------------- */ + + +void FingerProtocol::get(const KURL& url ) +{ + //kdDebug() << "tdeio_finger::get(const KURL& url)" << endl ; + + this->parseCommandLine(url); + + //kdDebug() << "myURL: " << myURL->prettyURL() << endl; + + // Reset the stream + *myStdStream=""; + + TQString query = myURL->query(); + TQString refreshRate = defaultRefreshRate; + + //kdDebug() << "query: " << query << endl; + + // Check the validity of the query + + TQRegExp regExp("?refreshRate=[0-9][0-9]*", true, true); + if (query.contains(regExp)) { + //kdDebug() << "looks like a valid query" << endl; + TQRegExp regExp( "([0-9]+)" ); + regExp.search(query); + refreshRate = regExp.cap(0); + } + + //kdDebug() << "Refresh rate: " << refreshRate << endl; + + myTDEProcess = new TDEProcess(); + *myTDEProcess << *myPerlPath << *myFingerPerlScript + << *myFingerPath << *myFingerCSSFile + << refreshRate << myURL->host() << myURL->user() ; + + connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + //connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + // this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + data(TQCString(TQString(*myStdStream).local8Bit())); + + data(TQByteArray()); + finished(); + + //clean up + + delete myTDEProcess; +} + + +/* ---------------------------------------------------------------------------------- */ + + +void FingerProtocol::slotGetStdOutput(TDEProcess* /* p */, char *s, int len) +{ + //kdDebug() << "void FingerProtocol::slotGetStdoutOutput()" << endl; + *myStdStream += TQString::fromLocal8Bit(s, len); +} + + +/* ---------------------------------------------------------------------------------- */ + + +void FingerProtocol::mimetype(const KURL & /*url*/) +{ + mimeType("text/html"); + finished(); +} + + +/* ---------------------------------------------------------------------------------- */ + + +void FingerProtocol::getProgramPath() +{ + //kdDebug() << "kfingerMainWindow::getProgramPath()" << endl; + // Not to sure wether I'm using the right error number here. - schlpbch - + + myPerlPath = new TQString(TDEGlobal::dirs()->findExe("perl")); + if (myPerlPath->isEmpty()) + { + //kdDebug() << "Perl command not found" << endl; + this->error(ERR_CANNOT_LAUNCH_PROCESS, + i18n("Could not find the Perl program on your system, please install.")); + exit(); + } + else + { + //kdDebug() << "Perl command found:" << *myPerlPath << endl; + } + + myFingerPath = new TQString(TDEGlobal::dirs()->findExe("finger")); + if ((myFingerPath->isEmpty())) + { + //kdDebug() << "Finger command not found" << endl; + this->error(ERR_CANNOT_LAUNCH_PROCESS, + i18n("Could not find the Finger program on your system, please install.")); + exit(); + } + else + { + //kdDebug() << "Finger command found:" << *myFingerPath << endl; + } + + myFingerPerlScript = new TQString(locate("data","tdeio_finger/tdeio_finger.pl")); + if (myFingerPerlScript->isEmpty()) + { + //kdDebug() << "tdeio_finger.pl script not found" << endl; + this->error(ERR_CANNOT_LAUNCH_PROCESS, + i18n("tdeio_finger Perl script not found.")); + exit(); + } + else + { + //kdDebug() << "tdeio_finger perl script found: " << *myFingerPerlScript << endl; + } + + myFingerCSSFile = new TQString(locate("data","tdeio_finger/tdeio_finger.css")); + if (myFingerCSSFile->isEmpty()) + { + //kdDebug() << "tdeio_finger.css file not found" << endl; + this->warning(i18n("tdeio_finger CSS script not found. Output will look ugly.")); + } + else + { + //kdDebug() << "tdeio_finger CSS file found: " << *myFingerCSSFile << endl; + } +} + + +/* --------------------------------------------------------------------------- */ + + +void FingerProtocol::parseCommandLine(const KURL& url) +{ + myURL = new KURL(url); + + /* + * Generate a valid finger url + */ + + if(myURL->isEmpty() || !myURL->isValid() || + (myURL->user().isEmpty() && myURL->host().isEmpty())) + { + myURL->setProtocol("finger"); + myURL->setUser(""); + myURL->setHost("localhost"); + } + + /* + * If no specific port is specified, set it to 79. + */ + + if(myURL->port() == 0) { + myURL->setPort(79); + } + + /* + * If no refresh rate is given, set it to defaultRefreshRate + */ + + if (myURL->query().isEmpty()) { + myURL->setQuery("?refreshRate="+defaultRefreshRate); + } +} + +/* ---------------------------------------------------------------------------------- */ +#include "tdeio_finger.moc" +/* ---------------------------------------------------------------------------------- */ + diff --git a/tdeioslave/finger/tdeio_finger.css b/tdeioslave/finger/tdeio_finger.css new file mode 100644 index 000000000..06deb81aa --- /dev/null +++ b/tdeioslave/finger/tdeio_finger.css @@ -0,0 +1,69 @@ +BODY { + color: #FFFFCC; + background-color: #000000; + padding: 2em; + margin: auto; +} + +A:link {color: #82A7D0} +A:visited {color: #999999} +A:active {color: #999999} + +H1 { + color: #999999; + background-color: #000000; + font: 200% Helvetica, sans-serif; + font-variant: normal; + padding: 1em; + margin: auto; +} + +.mainTable { + background-color: #000000; + border: thin solid; + margin: auto; +} + + +.courierText { + color: #FFFFCC; + background-color: #000000; + font: 120% Courier, sans-serif; + font-variant: normal; + text-align: left; + padding: 0em; +} + +.commandText { + color: #FFFFCC; + background-color: #000000; + font: 120% Courier, sans-serif; + font-variant: normal; + text-align: center; + padding: 0.5em; +} + +.niceText { + color: #009999; + background-color: #000000; + font: 120% Arial, sans-serif; + font-variant: normal; + text-align: center; + padding: 0.5em; +} + +.finger { color: #82A7D0} +.domainName { color: #D0A000} +.ipNumber { color: #D0A000} +.os { color: #82A7D0} +.username { color: #82A7D0} +.directory { color: #D0A000} +.shell { color: #D0A000} +.notLoggedIn { color: #00A000} +.loggedIn { color: #B00000} +.newMail { color: #82A7D0} +.plan { color: #D0A000} +.noNewMail { color: #BB0000} +.noPlan { color: #BB0000} + + diff --git a/tdeioslave/finger/tdeio_finger.h b/tdeioslave/finger/tdeio_finger.h new file mode 100644 index 000000000..3d083d2ed --- /dev/null +++ b/tdeioslave/finger/tdeio_finger.h @@ -0,0 +1,64 @@ + +/*************************************************************************** + tdeio_finger.h - description + ------------------- + begin : Sun Aug 12 2000 + copyright : (C) 2000 by Andreas Schlapbach + email : schlpbch@iam.unibe.ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#ifndef __tdeio_finger_h__ +#define __tdeio_finger_h__ + +#include +#include + +#include +#include +#include +#include + +class FingerProtocol : public TQObject, public TDEIO::SlaveBase +{ + Q_OBJECT + +public: + + FingerProtocol(const TQCString &pool_socket, const TQCString &app_socket); + virtual ~FingerProtocol(); + + virtual void mimetype(const KURL& url); + virtual void get(const KURL& url); + +private slots: + void slotGetStdOutput(TDEProcess*, char*, int); + +private: + KURL *myURL; + + QString *myPerlPath; + TQString *myFingerPath; + TQString *myFingerPerlScript; + TQString *myFingerCSSFile; + + QString *myStdStream; + + + TDEProcess *myTDEProcess; + + void getProgramPath(); + void parseCommandLine(const KURL& url); +}; + + +#endif diff --git a/tdeioslave/finger/tdeio_finger.pl b/tdeioslave/finger/tdeio_finger.pl new file mode 100644 index 000000000..8965ea523 --- /dev/null +++ b/tdeioslave/finger/tdeio_finger.pl @@ -0,0 +1,175 @@ +##!/usr/bin/perl +# +# Copyright Andreas Schlapbach, schlpbch@iam.unibe.ch, 2001 +# http://iamexwiwww.unibe.ch/studenten/kfinger +# +# Touch at your own risk. + + +# Highlight mail addresses or url + +$mails = '/>/g; + +$USER =~ s/&/&/g; +$USER =~ s//>/g; + +# HTML Header + +print < + + + + finger $USER\@$HOST + + + + + + + + + \n"; + +# Finger-Talk options + +if ($USER) # is $USER nil ? +{ +print < + + + +UserQuery +} +else +{ +print < +
+

finger $USER\@$HOST

+
+ +HTMLHeader + +# Run finger command and save it into a buffer + +open(F, "-|") || exec $FINGERCMD, "$USER\@$HOST"; +@lines = ; +close(F); + +# Do highlighting using perl regular expressions on every line received. +# Order is important here. + +foreach $output (@lines) + { + $output =~ s/((\w)+\@((\w)+(.))*(\w)+)/$mails$1$urlspace$1$urlend/gi; # Highlight email address + $output =~ s/((http|ftp)(:\/\/)(\S)+)/$urls$1$urlspace$1$urlend/gi; # Highlight urls + $output =~ s/((\d)+\.(\d)+\.(\d)+\.(\d)+)/$ipNumber$1$close/gi; # Highlight IP number + $output =~ s/((\w)+\.(\w)+\.(\w|-)+\s)/$domainName$1$close/gi; # Highlight domain name (\s is important) + $output =~ s/(finger:)/$finger$1$close/gim; # Highlight finger + $output =~ s/(Linux)/$os$1$close/gim; # Highlight Linux + if ($USER) # is $USER nil ? + { + $output =~ s/^Login:\s*(\w*)/Login: $mails$1\@$HOST$urlspace$1$urlend/gi; + $output =~ s/^Login Name:\s*(\w*)/Login Name:$mails$1\@$HOST$urlspace$1$urlend/gi; + $output =~ s/Name:(((\s*)(\w+))+\n)/Name:$username$1$close\n/gi; # Linux + $output =~ s/In real life:(((\s*)(\w+))+\n)/In real life:$username$1$close\n/gi; # Solaris + $output =~ s/^Directory:((\s*)(\/(\w)+)+)/Directory:$directory$1$close/gi; # Highlight Directory + $output =~ s/Shell:((\s*)(\/(\w)+)+)/Shell:$shell$1$close/gi; # Highlight Shell + $output =~ s/(not presently logged)/$notLoggedIn$1$close/gi; + $output =~ s/con (\w*)/con $loggedIn$1$close/gi; + $output =~ s/^(New mail)/$newMail$1$close/gi; + $output =~ s/^(No mail.)/$noNewMail$1$close/gim; + $output =~ s/^(Plan:)/$plan$1$close/gi; + $output =~ s/^(No plan.)/$noPlan$1$close/gim; + } + else + { + $output =~ s/^(\w+)/$mails$1\@$HOST$urlspace$1$urlend/m unless ($output =~ m/$keywordlist/m); + } + # line consists of white space only? + if ($output =~ m/\S/gi) + { + print " \n"; + } + else + { + print " \n"; + } +} + +print "
$output
  
\n"; +print "
+ finger +
+HostQueryHead + + @lines = split /^/m, $buffer; + foreach $output2 (@lines) + { + if ($output2 =~ m/^(\w+)/gi and not ($output2 =~ m/$keywordlist/m)) + { + $USER = $&; + print " \n"; + # - talk\n\n"; + } + else + { + print " \n"; + } + } + +print < + + +HostQueryTail +} + +# HTMLTail + +print < + + +
finger\n
  
refresh rate: $REFRESHRATE seconds.
+ + +HTMLTail diff --git a/tdeioslave/fish/CMakeLists.txt b/tdeioslave/fish/CMakeLists.txt index 445ea418f..b0498131a 100644 --- a/tdeioslave/fish/CMakeLists.txt +++ b/tdeioslave/fish/CMakeLists.txt @@ -28,7 +28,7 @@ link_directories( install( FILES fish.protocol nxfish.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_fish (module) ######################### +##### tdeio_fish (module) ######################### add_custom_command( OUTPUT fishcode.h COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/genfishcode.pl ${CMAKE_CURRENT_SOURCE_DIR}/fish.pl > fishcode.h @@ -36,7 +36,7 @@ add_custom_command( OUTPUT fishcode.h set_property( SOURCE fish.cpp APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/fishcode.h ) -set( target kio_fish ) +set( target tdeio_fish ) tde_add_kpart( ${target} AUTOMOC SOURCES fish.cpp diff --git a/tdeioslave/fish/FAQ b/tdeioslave/fish/FAQ index dce0aef41..6c96494e7 100644 --- a/tdeioslave/fish/FAQ +++ b/tdeioslave/fish/FAQ @@ -1,4 +1,4 @@ -Freqeuently Asked Questions, last updated for kio_fish 1.1 +Freqeuently Asked Questions, last updated for tdeio_fish 1.1 Q: Typing fish:/some.host.com does not work A: It is fish://some.host.com (double slash) diff --git a/tdeioslave/fish/Makefile.am b/tdeioslave/fish/Makefile.am index 35ca64fd4..e060da76f 100644 --- a/tdeioslave/fish/Makefile.am +++ b/tdeioslave/fish/Makefile.am @@ -1,11 +1,11 @@ -kde_module_LTLIBRARIES = kio_fish.la +kde_module_LTLIBRARIES = tdeio_fish.la INCLUDES = $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -kio_fish_la_SOURCES = fish.cpp -kio_fish_la_LIBADD = $(LIB_KSYCOCA) $(LIBUTIL) -kio_fish_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -lutil +tdeio_fish_la_SOURCES = fish.cpp +tdeio_fish_la_LIBADD = $(LIB_KSYCOCA) $(LIBUTIL) +tdeio_fish_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -lutil noinst_HEADERS = fishcode.h fish.h EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO FAQ fish.pl diff --git a/tdeioslave/fish/README b/tdeioslave/fish/README index d1afdc3d1..d71098256 100644 --- a/tdeioslave/fish/README +++ b/tdeioslave/fish/README @@ -1,4 +1,4 @@ -Overview of kio_fish +Overview of tdeio_fish ==================== ------------------------------------------------------------------------ diff --git a/tdeioslave/fish/fish.cpp b/tdeioslave/fish/fish.cpp index 0bf44482e..30f033753 100644 --- a/tdeioslave/fish/fish.cpp +++ b/tdeioslave/fish/fish.cpp @@ -126,7 +126,7 @@ static void ripper(int) int KDE_EXPORT kdemain( int argc, char **argv ) { - KLocale::setMainCatalogue("kio_fish"); + KLocale::setMainCatalogue("tdeio_fish"); TDEInstance instance("fish"); myDebug( << "*** Starting fish " << endl); diff --git a/tdeioslave/fish/fish.pl b/tdeioslave/fish/fish.pl index 1fe13841f..ace813bb9 100755 --- a/tdeioslave/fish/fish.pl +++ b/tdeioslave/fish/fish.pl @@ -3,9 +3,9 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 2 of the License =pod -This file was transferred by kio_fish, a network client part of the +This file was transferred by tdeio_fish, a network client part of the KDE project. You may safely delete it, it will be transferred again -when needed. It's only purpose is to make kio_fish access faster and +when needed. It's only purpose is to make tdeio_fish access faster and more reliable. =cut diff --git a/tdeioslave/fish/fish.protocol b/tdeioslave/fish/fish.protocol index 451050fcf..dfff5a789 100644 --- a/tdeioslave/fish/fish.protocol +++ b/tdeioslave/fish/fish.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_fish +exec=tdeio_fish protocol=fish input=none output=filesystem diff --git a/tdeioslave/fish/nxfish.protocol b/tdeioslave/fish/nxfish.protocol index 1a6ffbb48..27f1fb853 100644 --- a/tdeioslave/fish/nxfish.protocol +++ b/tdeioslave/fish/nxfish.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_fish +exec=tdeio_fish protocol=nxfish input=none output=filesystem diff --git a/tdeioslave/floppy/CMakeLists.txt b/tdeioslave/floppy/CMakeLists.txt index b328998ab..3ce6ffe01 100644 --- a/tdeioslave/floppy/CMakeLists.txt +++ b/tdeioslave/floppy/CMakeLists.txt @@ -26,12 +26,12 @@ link_directories( install( FILES floppy.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_floppy (module) ####################### +##### tdeio_floppy (module) ####################### -set( target kio_floppy ) +set( target tdeio_floppy ) set( ${target}_SRCS - kio_floppy.cpp program.cpp + tdeio_floppy.cpp program.cpp ) tde_add_kpart( ${target} AUTOMOC diff --git a/tdeioslave/floppy/Makefile.am b/tdeioslave/floppy/Makefile.am index ec422f75d..e6b52fe17 100644 --- a/tdeioslave/floppy/Makefile.am +++ b/tdeioslave/floppy/Makefile.am @@ -5,11 +5,11 @@ AM_LDFLAGS = $(all_libraries) ####### Files -kde_module_LTLIBRARIES = kio_floppy.la +kde_module_LTLIBRARIES = tdeio_floppy.la -kio_floppy_la_SOURCES = kio_floppy.cpp program.cpp -kio_floppy_la_LIBADD = $(LIB_KIO) -kio_floppy_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_floppy_la_SOURCES = tdeio_floppy.cpp program.cpp +tdeio_floppy_la_LIBADD = $(LIB_KIO) +tdeio_floppy_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) kdelnk_DATA = floppy.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/floppy/floppy.protocol b/tdeioslave/floppy/floppy.protocol index af861d1be..84a1b12b8 100644 --- a/tdeioslave/floppy/floppy.protocol +++ b/tdeioslave/floppy/floppy.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_floppy +exec=tdeio_floppy protocol=floppy input=none output=filesystem diff --git a/tdeioslave/floppy/kio_floppy.cpp b/tdeioslave/floppy/kio_floppy.cpp deleted file mode 100644 index 626a4a1f0..000000000 --- a/tdeioslave/floppy/kio_floppy.cpp +++ /dev/null @@ -1,1169 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2000 Alexander Neundorf - - 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. -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kio_floppy.h" - -#include -#include -#include -#include - -using namespace TDEIO; - -extern "C" { KDE_EXPORT int kdemain(int argc, char **argv); } - -int kdemain( int argc, char **argv ) -{ - TDEInstance instance( "kio_floppy" ); - - if (argc != 4) - { - fprintf(stderr, "Usage: kio_floppy protocol domain-socket1 domain-socket2\n"); - exit(-1); - } - kdDebug(7101) << "Floppy: kdemain: starting" << endl; - - FloppyProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - return 0; -} - -void getDriveAndPath(const TQString& path, TQString& drive, TQString& rest) -{ - drive=TQString::null; - rest=TQString::null; - TQStringList list=TQStringList::split("/",path); - for (TQStringList::Iterator it=list.begin(); it!=list.end(); it++) - { - if (it==list.begin()) - drive=(*it)+":"; - else - rest=rest+"/"+(*it); - } -} - -FloppyProtocol::FloppyProtocol (const TQCString &pool, const TQCString &app ) -:SlaveBase( "floppy", pool, app ) -,m_mtool(0) -,m_stdoutBuffer(0) -,m_stderrBuffer(0) -,m_stdoutSize(0) -,m_stderrSize(0) -{ - kdDebug(7101)<<"Floppy::Floppy: -"<stdoutFD(),buffer,16*1024); - if (length<=0) return 0; - - //+1 gives us room for a terminating 0 - char *newBuffer=new char[length+m_stdoutSize+1]; - kdDebug(7101)<<"Floppy::readStdout(): length: "<stderrFD(),buffer,16*1024); - kdDebug(7101)<<"Floppy::readStderr(): read "< -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access drive %1.\nThe drive is still busy.\nWait until it is inactive and then try again.").arg(drive)); - } - else if ((line.find("Disk full") > -1) || (line.find("No free cluster") > -1)) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not write to file %1.\nThe disk in drive %2 is probably full.").arg(url.prettyURL(),drive)); - } - //file not found - else if (line.find("not found") > -1) - { - error( TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - } - //no disk - else if (line.find("not configured") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThere is probably no disk in the drive %2").arg(url.prettyURL(),drive)); - } - else if (line.find("No such device") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThere is probably no disk in the drive %2 or you do not have enough permissions to access the drive.").arg(url.prettyURL(),drive)); - } - else if (line.find("not supported") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThe drive %2 is not supported.").arg(url.prettyURL(),drive)); - } - //not supported or no such drive - else if (line.find("Permission denied") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nMake sure the floppy in drive %2 is a DOS-formatted floppy disk \nand that the permissions of the device file (e.g. /dev/fd0) are set correctly (e.g. rwxrwxrwx).").arg(url.prettyURL(),drive)); - } - else if (line.find("non DOS media") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThe disk in drive %2 is probably not a DOS-formatted floppy disk.").arg(url.prettyURL(),drive)); - } - else if (line.find("Read-only") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Access denied.\nCould not write to %1.\nThe disk in drive %2 is probably write-protected.").arg(url.prettyURL(),drive)); - } - else if ((outputString.find("already exists") > -1) || (outputString.find("Skipping ") > -1)) - { - error( TDEIO::ERR_FILE_ALREADY_EXIST,url.prettyURL()); - //return false; - } - else if (outputString.find("could not read boot sector") > -1) - { - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not read boot sector for %1.\nThere is probably not any disk in drive %2.").arg(url.prettyURL(),drive)); - //return false; - } - else - { - error( TDEIO::ERR_UNKNOWN, outputString); - } - return true; -} - -void FloppyProtocol::listDir( const KURL& _url) -{ - kdDebug(7101)<<"Floppy::listDir() "<<_url.path()<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mdir"); - return; - } - - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(url,drive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - delete m_mtool; - m_mtool=0; - //now mdir has finished - //let's parse the output - terminateBuffers(); - - if (errorOccured) - return; - - TQString outputString(m_stdoutBuffer); - TQTextIStream output(&outputString); - TQString line; - - int totalNumber(0); - int mode(0); - UDSEntry entry; - - while (!output.atEnd()) - { - line=output.readLine(); - kdDebug(7101)<<"Floppy::listDir(): line: -"<0) - { - name=line.mid(0,nameLength); - TQString ext=line.mid(9,3); - ext=ext.stripWhiteSpace(); - if (!ext.isEmpty()) - name+="."+ext; - } - kdDebug(7101)<<"Floppy::createStatInfo() name 8.3= -"<41) - { - name=line.mid(42); - kdDebug(7101)<<"Floppy::createStatInfo() name vfat: -"<") - { - //kdDebug(7101)<<"Floppy::createUDSEntry() isDir"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mdir"); - return info; - } - - - clearBuffers(); - - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(url,drive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - //kdDebug(7101)<<"Floppy::_stat(): delete m_mtool"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mdir"); - return -1; - } - - - clearBuffers(); - - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(url,drive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - //kdDebug(7101)<<"Floppy::freeSpace(): delete m_mtool"<_stat(url); - if (info.isValid) - { - UDSEntry entry; - createUDSEntry(info,entry); - statEntry( entry ); - finished(); - //kdDebug(7101)<<"Floppy::stat(): ends"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mmd"); - return; - } - - - clearBuffers(); - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(url,drive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - delete m_mtool; - m_mtool=0; - terminateBuffers(); - if (errorOccured) - return; - finished(); -} - -void FloppyProtocol::del( const KURL& url, bool isfile) -{ - kdDebug(7101)<<"FloppyProtocol::del()"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram(usingmdel ? TQString("mdel") : TQString("mrd")); - return; - } - - - clearBuffers(); - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(url,drive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - delete m_mtool; - m_mtool=0; - terminateBuffers(); - if (errorOccured) - return; - finished(); -} - -void FloppyProtocol::rename( const KURL &src, const KURL &dest, bool _overwrite ) -{ - TQString srcPath(src.path()); - TQString destPath(dest.path()); - - kdDebug(7101)<<"Floppy::rename() -"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mren"); - return; - } - - - clearBuffers(); - int result; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - if (readStdout()==0) - loopFinished=true; - if (stderrEvent) - { - if (readStderr()==0) - loopFinished=true; - else - if (stopAfterError(src,srcDrive)) - { - loopFinished=true; - errorOccured=true; - } - } - } while (!loopFinished); - - delete m_mtool; - m_mtool=0; - terminateBuffers(); - if (errorOccured) - return; - finished(); -} - -void FloppyProtocol::get( const KURL& url ) -{ - TQString path(url.path()); - kdDebug(7101)<<"Floppy::get() -"<_stat(url); - //the error was already reported in _stat() - if (info.isValid==false) - return; - - totalSize( info.size); - - TQString drive; - TQString floppyPath; - getDriveAndPath(path,drive,floppyPath); - if (floppyPath.isEmpty()) - { - finished(); - return; - } - - if (m_mtool!=0) - delete m_mtool; - //kdDebug(7101)<<"Floppy::stat(): create args"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mcopy"); - return; - } - - clearBuffers(); - int result; - int bytesRead(0); - TQByteArray array; - bool loopFinished(false); - bool errorOccured(false); - do - { - bool stdoutEvent; - bool stderrEvent; - result=m_mtool->select(1,0,stdoutEvent, stderrEvent); - if (stdoutEvent) - { - delete [] m_stdoutBuffer; - m_stdoutBuffer=0; - m_stdoutSize=0; - if (readStdout()>0) - { - kdDebug(7101)<<"Floppy::get(): m_stdoutSize:"<start()) - { - delete m_mtool; - m_mtool=0; - errorMissingMToolsProgram("mcopy"); - return; - } - - - clearBuffers(); - int result(0); - int bytesRead(0); - TQByteArray array; - - //from file.cc - // Loop until we got 0 (end of data) - do - { - bool stdoutEvent; - bool stderrEvent; - kdDebug(7101)<<"Floppy::put(): select()..."<select(0,100,stdoutEvent, stderrEvent); - if (stdoutEvent) - { - if (readStdout()==0) - result=0; - } - if (stderrEvent) - { - if (readStderr()==0) - result=0; - else - if (stopAfterError(url,drive)) - result=-1; - kdDebug(7101)<<"Floppy::put(): error: result=="< 0) - { - bytesRead+=result; - kdDebug(7101)<<"Floppy::put() bytesRead: "<freeSpaceLeft) - { - result=0; - error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not write to file %1.\nThe disk in drive %2 is probably full.").arg(url.prettyURL(),drive)); - } - else - { - //kdDebug(7101)<<"Floppy::put(): writing..."<stdinFD(),buffer.data(), buffer.size()); - kdDebug(7101)<<"Floppy::put(): after write(), wrote "< 0 ); - - if (result<0) - { - perror("writing to stdin"); - error( TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, url.prettyURL()); - return; - } - - delete m_mtool; - m_mtool=0; - - finished(); -} - diff --git a/tdeioslave/floppy/kio_floppy.h b/tdeioslave/floppy/kio_floppy.h deleted file mode 100644 index d38340729..000000000 --- a/tdeioslave/floppy/kio_floppy.h +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Alexander Neundorf - - 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_FLOPPY_H -#define KIO_FLOPPY_H - -#include -#include - -#include "program.h" - -#include - -struct StatInfo -{ - StatInfo():name(""),time(0),size(0),mode(0),freeSpace(0),isDir(false),isValid(false) {;} - TQString name; - time_t time; - int size; - int mode; - int freeSpace; - bool isDir:1; - bool isValid:1; -}; - - -class FloppyProtocol : public TDEIO::SlaveBase -{ - public: - FloppyProtocol (const TQCString &pool, const TQCString &app ); - virtual ~FloppyProtocol(); - - virtual void listDir( const KURL& url); - virtual void stat( const KURL & url); - virtual void mkdir( const KURL& url, int); - virtual void del( const KURL& url, bool isfile); - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - virtual void get( const KURL& url ); - virtual void put( const KURL& url, int _mode,bool overwrite, bool _resume ); - //virtual void copy( const KURL& src, const KURL &dest, int, bool overwrite ); - protected: - Program *m_mtool; - int readStdout(); - int readStderr(); - - StatInfo createStatInfo(const TQString line, bool makeStat=false, const TQString& dirName=""); - void createUDSEntry(const StatInfo& info, TDEIO::UDSEntry& entry); - StatInfo _stat(const KURL& _url); - int freeSpace(const KURL& url); - - bool stopAfterError(const KURL& url, const TQString& drive); - void errorMissingMToolsProgram(const TQString& name); - - void clearBuffers(); - void terminateBuffers(); - char *m_stdoutBuffer; - char *m_stderrBuffer; - int m_stdoutSize; - int m_stderrSize; -}; - -#endif diff --git a/tdeioslave/floppy/tdeio_floppy.cpp b/tdeioslave/floppy/tdeio_floppy.cpp new file mode 100644 index 000000000..0e576e472 --- /dev/null +++ b/tdeioslave/floppy/tdeio_floppy.cpp @@ -0,0 +1,1169 @@ +/* This file is part of the KDE project + + Copyright (C) 2000 Alexander Neundorf + + 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. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "tdeio_floppy.h" + +#include +#include +#include +#include + +using namespace TDEIO; + +extern "C" { KDE_EXPORT int kdemain(int argc, char **argv); } + +int kdemain( int argc, char **argv ) +{ + TDEInstance instance( "tdeio_floppy" ); + + if (argc != 4) + { + fprintf(stderr, "Usage: tdeio_floppy protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + kdDebug(7101) << "Floppy: kdemain: starting" << endl; + + FloppyProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; +} + +void getDriveAndPath(const TQString& path, TQString& drive, TQString& rest) +{ + drive=TQString::null; + rest=TQString::null; + TQStringList list=TQStringList::split("/",path); + for (TQStringList::Iterator it=list.begin(); it!=list.end(); it++) + { + if (it==list.begin()) + drive=(*it)+":"; + else + rest=rest+"/"+(*it); + } +} + +FloppyProtocol::FloppyProtocol (const TQCString &pool, const TQCString &app ) +:SlaveBase( "floppy", pool, app ) +,m_mtool(0) +,m_stdoutBuffer(0) +,m_stderrBuffer(0) +,m_stdoutSize(0) +,m_stderrSize(0) +{ + kdDebug(7101)<<"Floppy::Floppy: -"<stdoutFD(),buffer,16*1024); + if (length<=0) return 0; + + //+1 gives us room for a terminating 0 + char *newBuffer=new char[length+m_stdoutSize+1]; + kdDebug(7101)<<"Floppy::readStdout(): length: "<stderrFD(),buffer,16*1024); + kdDebug(7101)<<"Floppy::readStderr(): read "< -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access drive %1.\nThe drive is still busy.\nWait until it is inactive and then try again.").arg(drive)); + } + else if ((line.find("Disk full") > -1) || (line.find("No free cluster") > -1)) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not write to file %1.\nThe disk in drive %2 is probably full.").arg(url.prettyURL(),drive)); + } + //file not found + else if (line.find("not found") > -1) + { + error( TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + //no disk + else if (line.find("not configured") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThere is probably no disk in the drive %2").arg(url.prettyURL(),drive)); + } + else if (line.find("No such device") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThere is probably no disk in the drive %2 or you do not have enough permissions to access the drive.").arg(url.prettyURL(),drive)); + } + else if (line.find("not supported") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThe drive %2 is not supported.").arg(url.prettyURL(),drive)); + } + //not supported or no such drive + else if (line.find("Permission denied") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nMake sure the floppy in drive %2 is a DOS-formatted floppy disk \nand that the permissions of the device file (e.g. /dev/fd0) are set correctly (e.g. rwxrwxrwx).").arg(url.prettyURL(),drive)); + } + else if (line.find("non DOS media") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not access %1.\nThe disk in drive %2 is probably not a DOS-formatted floppy disk.").arg(url.prettyURL(),drive)); + } + else if (line.find("Read-only") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Access denied.\nCould not write to %1.\nThe disk in drive %2 is probably write-protected.").arg(url.prettyURL(),drive)); + } + else if ((outputString.find("already exists") > -1) || (outputString.find("Skipping ") > -1)) + { + error( TDEIO::ERR_FILE_ALREADY_EXIST,url.prettyURL()); + //return false; + } + else if (outputString.find("could not read boot sector") > -1) + { + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not read boot sector for %1.\nThere is probably not any disk in drive %2.").arg(url.prettyURL(),drive)); + //return false; + } + else + { + error( TDEIO::ERR_UNKNOWN, outputString); + } + return true; +} + +void FloppyProtocol::listDir( const KURL& _url) +{ + kdDebug(7101)<<"Floppy::listDir() "<<_url.path()<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mdir"); + return; + } + + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(url,drive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + delete m_mtool; + m_mtool=0; + //now mdir has finished + //let's parse the output + terminateBuffers(); + + if (errorOccured) + return; + + TQString outputString(m_stdoutBuffer); + TQTextIStream output(&outputString); + TQString line; + + int totalNumber(0); + int mode(0); + UDSEntry entry; + + while (!output.atEnd()) + { + line=output.readLine(); + kdDebug(7101)<<"Floppy::listDir(): line: -"<0) + { + name=line.mid(0,nameLength); + TQString ext=line.mid(9,3); + ext=ext.stripWhiteSpace(); + if (!ext.isEmpty()) + name+="."+ext; + } + kdDebug(7101)<<"Floppy::createStatInfo() name 8.3= -"<41) + { + name=line.mid(42); + kdDebug(7101)<<"Floppy::createStatInfo() name vfat: -"<") + { + //kdDebug(7101)<<"Floppy::createUDSEntry() isDir"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mdir"); + return info; + } + + + clearBuffers(); + + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(url,drive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + //kdDebug(7101)<<"Floppy::_stat(): delete m_mtool"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mdir"); + return -1; + } + + + clearBuffers(); + + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(url,drive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + //kdDebug(7101)<<"Floppy::freeSpace(): delete m_mtool"<_stat(url); + if (info.isValid) + { + UDSEntry entry; + createUDSEntry(info,entry); + statEntry( entry ); + finished(); + //kdDebug(7101)<<"Floppy::stat(): ends"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mmd"); + return; + } + + + clearBuffers(); + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(url,drive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + delete m_mtool; + m_mtool=0; + terminateBuffers(); + if (errorOccured) + return; + finished(); +} + +void FloppyProtocol::del( const KURL& url, bool isfile) +{ + kdDebug(7101)<<"FloppyProtocol::del()"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram(usingmdel ? TQString("mdel") : TQString("mrd")); + return; + } + + + clearBuffers(); + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(url,drive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + delete m_mtool; + m_mtool=0; + terminateBuffers(); + if (errorOccured) + return; + finished(); +} + +void FloppyProtocol::rename( const KURL &src, const KURL &dest, bool _overwrite ) +{ + TQString srcPath(src.path()); + TQString destPath(dest.path()); + + kdDebug(7101)<<"Floppy::rename() -"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mren"); + return; + } + + + clearBuffers(); + int result; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + if (readStdout()==0) + loopFinished=true; + if (stderrEvent) + { + if (readStderr()==0) + loopFinished=true; + else + if (stopAfterError(src,srcDrive)) + { + loopFinished=true; + errorOccured=true; + } + } + } while (!loopFinished); + + delete m_mtool; + m_mtool=0; + terminateBuffers(); + if (errorOccured) + return; + finished(); +} + +void FloppyProtocol::get( const KURL& url ) +{ + TQString path(url.path()); + kdDebug(7101)<<"Floppy::get() -"<_stat(url); + //the error was already reported in _stat() + if (info.isValid==false) + return; + + totalSize( info.size); + + TQString drive; + TQString floppyPath; + getDriveAndPath(path,drive,floppyPath); + if (floppyPath.isEmpty()) + { + finished(); + return; + } + + if (m_mtool!=0) + delete m_mtool; + //kdDebug(7101)<<"Floppy::stat(): create args"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mcopy"); + return; + } + + clearBuffers(); + int result; + int bytesRead(0); + TQByteArray array; + bool loopFinished(false); + bool errorOccured(false); + do + { + bool stdoutEvent; + bool stderrEvent; + result=m_mtool->select(1,0,stdoutEvent, stderrEvent); + if (stdoutEvent) + { + delete [] m_stdoutBuffer; + m_stdoutBuffer=0; + m_stdoutSize=0; + if (readStdout()>0) + { + kdDebug(7101)<<"Floppy::get(): m_stdoutSize:"<start()) + { + delete m_mtool; + m_mtool=0; + errorMissingMToolsProgram("mcopy"); + return; + } + + + clearBuffers(); + int result(0); + int bytesRead(0); + TQByteArray array; + + //from file.cc + // Loop until we got 0 (end of data) + do + { + bool stdoutEvent; + bool stderrEvent; + kdDebug(7101)<<"Floppy::put(): select()..."<select(0,100,stdoutEvent, stderrEvent); + if (stdoutEvent) + { + if (readStdout()==0) + result=0; + } + if (stderrEvent) + { + if (readStderr()==0) + result=0; + else + if (stopAfterError(url,drive)) + result=-1; + kdDebug(7101)<<"Floppy::put(): error: result=="< 0) + { + bytesRead+=result; + kdDebug(7101)<<"Floppy::put() bytesRead: "<freeSpaceLeft) + { + result=0; + error( TDEIO::ERR_SLAVE_DEFINED, i18n("Could not write to file %1.\nThe disk in drive %2 is probably full.").arg(url.prettyURL(),drive)); + } + else + { + //kdDebug(7101)<<"Floppy::put(): writing..."<stdinFD(),buffer.data(), buffer.size()); + kdDebug(7101)<<"Floppy::put(): after write(), wrote "< 0 ); + + if (result<0) + { + perror("writing to stdin"); + error( TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, url.prettyURL()); + return; + } + + delete m_mtool; + m_mtool=0; + + finished(); +} + diff --git a/tdeioslave/floppy/tdeio_floppy.h b/tdeioslave/floppy/tdeio_floppy.h new file mode 100644 index 000000000..d38340729 --- /dev/null +++ b/tdeioslave/floppy/tdeio_floppy.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf + + 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_FLOPPY_H +#define KIO_FLOPPY_H + +#include +#include + +#include "program.h" + +#include + +struct StatInfo +{ + StatInfo():name(""),time(0),size(0),mode(0),freeSpace(0),isDir(false),isValid(false) {;} + TQString name; + time_t time; + int size; + int mode; + int freeSpace; + bool isDir:1; + bool isValid:1; +}; + + +class FloppyProtocol : public TDEIO::SlaveBase +{ + public: + FloppyProtocol (const TQCString &pool, const TQCString &app ); + virtual ~FloppyProtocol(); + + virtual void listDir( const KURL& url); + virtual void stat( const KURL & url); + virtual void mkdir( const KURL& url, int); + virtual void del( const KURL& url, bool isfile); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void get( const KURL& url ); + virtual void put( const KURL& url, int _mode,bool overwrite, bool _resume ); + //virtual void copy( const KURL& src, const KURL &dest, int, bool overwrite ); + protected: + Program *m_mtool; + int readStdout(); + int readStderr(); + + StatInfo createStatInfo(const TQString line, bool makeStat=false, const TQString& dirName=""); + void createUDSEntry(const StatInfo& info, TDEIO::UDSEntry& entry); + StatInfo _stat(const KURL& _url); + int freeSpace(const KURL& url); + + bool stopAfterError(const KURL& url, const TQString& drive); + void errorMissingMToolsProgram(const TQString& name); + + void clearBuffers(); + void terminateBuffers(); + char *m_stdoutBuffer; + char *m_stderrBuffer; + int m_stdoutSize; + int m_stderrSize; +}; + +#endif diff --git a/tdeioslave/home/CMakeLists.txt b/tdeioslave/home/CMakeLists.txt index bfc9e6cff..3d569681f 100644 --- a/tdeioslave/home/CMakeLists.txt +++ b/tdeioslave/home/CMakeLists.txt @@ -27,22 +27,22 @@ link_directories( install( FILES home.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kiohome (static) ########################## +##### tdeiohome (static) ########################## -set( target kiohome ) +set( target tdeiohome ) tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES kio_home.cpp homeimpl.cpp + SOURCES tdeio_home.cpp homeimpl.cpp ) -##### kio_home (module) ######################### +##### tdeio_home (module) ######################### -set( target kio_home ) +set( target tdeio_home ) tde_add_kpart( ${target} SOURCES dummy.cpp - EMBED kiohome-static + EMBED tdeiohome-static LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/home/Makefile.am b/tdeioslave/home/Makefile.am index 38b73e653..d40341aab 100644 --- a/tdeioslave/home/Makefile.am +++ b/tdeioslave/home/Makefile.am @@ -4,11 +4,11 @@ SUBDIRS= . kdedmodule INCLUDES = $(all_includes) METASOURCES = AUTO -kde_module_LTLIBRARIES = kio_home.la +kde_module_LTLIBRARIES = tdeio_home.la -kio_home_la_SOURCES = dummy.cpp -kio_home_la_LIBADD = libtdeiohome.la $(LIB_KIO) -kio_home_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined +tdeio_home_la_SOURCES = dummy.cpp +tdeio_home_la_LIBADD = libtdeiohome.la $(LIB_KIO) +tdeio_home_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined dummy.cpp: echo > dummy.cpp @@ -16,7 +16,7 @@ dummy.cpp: kde_services_DATA = home.protocol noinst_LTLIBRARIES = libtdeiohome.la -libtdeiohome_la_SOURCES = kio_home.cpp homeimpl.cpp +libtdeiohome_la_SOURCES = tdeio_home.cpp homeimpl.cpp check_PROGRAMS = testhome testhome_SOURCES = testhome.cpp diff --git a/tdeioslave/home/home.protocol b/tdeioslave/home/home.protocol index da2a556cd..53192efe0 100644 --- a/tdeioslave/home/home.protocol +++ b/tdeioslave/home/home.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_home +exec=tdeio_home protocol=home input=none output=filesystem diff --git a/tdeioslave/home/kdedmodule/homedirnotifymodule.cpp b/tdeioslave/home/kdedmodule/homedirnotifymodule.cpp index 4eb71c332..19bcff988 100644 --- a/tdeioslave/home/kdedmodule/homedirnotifymodule.cpp +++ b/tdeioslave/home/kdedmodule/homedirnotifymodule.cpp @@ -30,7 +30,7 @@ HomeDirNotifyModule::HomeDirNotifyModule(const TQCString &obj) extern "C" { KDE_EXPORT KDEDModule *create_homedirnotify(const TQCString &obj) { - TDEGlobal::locale()->insertCatalogue("kio_home"); + TDEGlobal::locale()->insertCatalogue("tdeio_home"); return new HomeDirNotifyModule(obj); } } diff --git a/tdeioslave/home/kio_home.cpp b/tdeioslave/home/kio_home.cpp deleted file mode 100644 index bd55aee0a..000000000 --- a/tdeioslave/home/kio_home.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2005 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include -#include -#include -#include -#include - - -#include "kio_home.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 ) - { - // TDEApplication is necessary to use other ioslaves - putenv(strdup("SESSION_MANAGER=")); - TDECmdLineArgs::init(argc, argv, "kio_home", 0, 0, 0, 0); - TDECmdLineArgs::addCmdLineOptions( options ); - TDEApplication app( false, false ); - // We want to be anonymous even if we use DCOP - app.dcopClient()->attach(); - - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - HomeProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); - slave.dispatchLoop(); - return 0; - } -} - - -HomeProtocol::HomeProtocol(const TQCString &protocol, - const TQCString &pool, const TQCString &app) - : ForwardingSlaveBase(protocol, pool, app) -{ -} - -HomeProtocol::~HomeProtocol() -{ -} - -bool HomeProtocol::rewriteURL(const KURL &url, KURL &newUrl) -{ - TQString name, path; - - if ( !m_impl.parseURL(url, name, path) ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return false; - } - - - if ( !m_impl.realURL(name, path, newUrl) ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return false; - } - - return true; -} - - -void HomeProtocol::listDir(const KURL &url) -{ - kdDebug() << "HomeProtocol::listDir: " << url << endl; - - if ( url.path().length() <= 1 ) - { - listRoot(); - return; - } - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - ForwardingSlaveBase::listDir(url); -} - -void HomeProtocol::listRoot() -{ - TDEIO::UDSEntry entry; - - TDEIO::UDSEntryList home_entries; - bool ok = m_impl.listHomes(home_entries); - - if (!ok) // can't happen - { - error(TDEIO::ERR_UNKNOWN, ""); - return; - } - - totalSize(home_entries.count()+1); - - m_impl.createTopLevelEntry(entry); - listEntry(entry, false); - - TDEIO::UDSEntryListIterator it = home_entries.begin(); - TDEIO::UDSEntryListIterator end = home_entries.end(); - - for(; it!=end; ++it) - { - listEntry(*it, false); - } - - entry.clear(); - listEntry(entry, true); - - finished(); -} - -void HomeProtocol::stat(const KURL &url) -{ - kdDebug() << "HomeProtocol::stat: " << url << endl; - - TQString path = url.path(); - if ( path.isEmpty() || path == "/" ) - { - // The root is "virtual" - it's not a single physical directory - TDEIO::UDSEntry entry; - m_impl.createTopLevelEntry( entry ); - statEntry( entry ); - finished(); - return; - } - - TQString name; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - if( path.isEmpty() ) - { - TDEIO::UDSEntry entry; - - if ( m_impl.statHome(name, entry) ) - { - statEntry(entry); - finished(); - } - else - { - error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - } - } - else - { - ForwardingSlaveBase::stat(url); - } -} diff --git a/tdeioslave/home/kio_home.h b/tdeioslave/home/kio_home.h deleted file mode 100644 index db5d8902c..000000000 --- a/tdeioslave/home/kio_home.h +++ /dev/null @@ -1,44 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2005 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KIO_HOME_H -#define KIO_HOME_H - -#include -#include "homeimpl.h" - -class HomeProtocol : public TDEIO::ForwardingSlaveBase -{ -public: - HomeProtocol(const TQCString &protocol, const TQCString &pool, - const TQCString &app); - virtual ~HomeProtocol(); - - virtual bool rewriteURL(const KURL &url, KURL &newUrl); - - virtual void listDir(const KURL &url); - virtual void stat(const KURL &url); - -private: - void listRoot(); - - HomeImpl m_impl; -}; - -#endif diff --git a/tdeioslave/home/tdeio_home.cpp b/tdeioslave/home/tdeio_home.cpp new file mode 100644 index 000000000..23d78778b --- /dev/null +++ b/tdeioslave/home/tdeio_home.cpp @@ -0,0 +1,186 @@ +/* This file is part of the KDE project + Copyright (c) 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include +#include + + +#include "tdeio_home.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 ) + { + // TDEApplication is necessary to use other ioslaves + putenv(strdup("SESSION_MANAGER=")); + TDECmdLineArgs::init(argc, argv, "tdeio_home", 0, 0, 0, 0); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication app( false, false ); + // We want to be anonymous even if we use DCOP + app.dcopClient()->attach(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + HomeProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); + slave.dispatchLoop(); + return 0; + } +} + + +HomeProtocol::HomeProtocol(const TQCString &protocol, + const TQCString &pool, const TQCString &app) + : ForwardingSlaveBase(protocol, pool, app) +{ +} + +HomeProtocol::~HomeProtocol() +{ +} + +bool HomeProtocol::rewriteURL(const KURL &url, KURL &newUrl) +{ + TQString name, path; + + if ( !m_impl.parseURL(url, name, path) ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return false; + } + + + if ( !m_impl.realURL(name, path, newUrl) ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return false; + } + + return true; +} + + +void HomeProtocol::listDir(const KURL &url) +{ + kdDebug() << "HomeProtocol::listDir: " << url << endl; + + if ( url.path().length() <= 1 ) + { + listRoot(); + return; + } + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + ForwardingSlaveBase::listDir(url); +} + +void HomeProtocol::listRoot() +{ + TDEIO::UDSEntry entry; + + TDEIO::UDSEntryList home_entries; + bool ok = m_impl.listHomes(home_entries); + + if (!ok) // can't happen + { + error(TDEIO::ERR_UNKNOWN, ""); + return; + } + + totalSize(home_entries.count()+1); + + m_impl.createTopLevelEntry(entry); + listEntry(entry, false); + + TDEIO::UDSEntryListIterator it = home_entries.begin(); + TDEIO::UDSEntryListIterator end = home_entries.end(); + + for(; it!=end; ++it) + { + listEntry(*it, false); + } + + entry.clear(); + listEntry(entry, true); + + finished(); +} + +void HomeProtocol::stat(const KURL &url) +{ + kdDebug() << "HomeProtocol::stat: " << url << endl; + + TQString path = url.path(); + if ( path.isEmpty() || path == "/" ) + { + // The root is "virtual" - it's not a single physical directory + TDEIO::UDSEntry entry; + m_impl.createTopLevelEntry( entry ); + statEntry( entry ); + finished(); + return; + } + + TQString name; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + if( path.isEmpty() ) + { + TDEIO::UDSEntry entry; + + if ( m_impl.statHome(name, entry) ) + { + statEntry(entry); + finished(); + } + else + { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + } + else + { + ForwardingSlaveBase::stat(url); + } +} diff --git a/tdeioslave/home/tdeio_home.h b/tdeioslave/home/tdeio_home.h new file mode 100644 index 000000000..db5d8902c --- /dev/null +++ b/tdeioslave/home/tdeio_home.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (c) 2005 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIO_HOME_H +#define KIO_HOME_H + +#include +#include "homeimpl.h" + +class HomeProtocol : public TDEIO::ForwardingSlaveBase +{ +public: + HomeProtocol(const TQCString &protocol, const TQCString &pool, + const TQCString &app); + virtual ~HomeProtocol(); + + virtual bool rewriteURL(const KURL &url, KURL &newUrl); + + virtual void listDir(const KURL &url); + virtual void stat(const KURL &url); + +private: + void listRoot(); + + HomeImpl m_impl; +}; + +#endif diff --git a/tdeioslave/home/testhome.cpp b/tdeioslave/home/testhome.cpp index 66b2df126..643c21e32 100644 --- a/tdeioslave/home/testhome.cpp +++ b/tdeioslave/home/testhome.cpp @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -#include "kio_home.h" +#include "tdeio_home.h" #include "testhome.h" #include diff --git a/tdeioslave/info/CMakeLists.txt b/tdeioslave/info/CMakeLists.txt index ed2a72f61..75fab8d92 100644 --- a/tdeioslave/info/CMakeLists.txt +++ b/tdeioslave/info/CMakeLists.txt @@ -27,9 +27,9 @@ install( FILES kde-info2html.conf DESTINATION ${DATA_INSTALL_DIR}/tdeio_info ) install( PROGRAMS kde-info2html DESTINATION ${DATA_INSTALL_DIR}/tdeio_info ) -##### kio_info (module) ######################### +##### tdeio_info (module) ######################### -set( target kio_info ) +set( target tdeio_info ) tde_add_kpart( ${target} AUTOMOC SOURCES info.cc diff --git a/tdeioslave/info/Makefile.am b/tdeioslave/info/Makefile.am index 37bbe3083..1b2d21f32 100644 --- a/tdeioslave/info/Makefile.am +++ b/tdeioslave/info/Makefile.am @@ -6,16 +6,16 @@ METASOURCES = AUTO ####### Files -kde_module_LTLIBRARIES = kio_info.la +kde_module_LTLIBRARIES = tdeio_info.la -kio_info_la_SOURCES = info.cc -kio_info_la_LIBADD = $(LIB_KIO) -kio_info_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_info_la_SOURCES = info.cc +tdeio_info_la_LIBADD = $(LIB_KIO) +tdeio_info_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = info.h kdelnk_DATA = info.protocol kdelnkdir = $(kde_servicesdir) -kio_info_data_DATA = kde-info2html.conf -kio_info_data_SCRIPTS = kde-info2html -kio_info_datadir = $(kde_datadir)/tdeio_info +tdeio_info_data_DATA = kde-info2html.conf +tdeio_info_data_SCRIPTS = kde-info2html +tdeio_info_datadir = $(kde_datadir)/tdeio_info diff --git a/tdeioslave/info/info.cc b/tdeioslave/info/info.cc index 71d2dc863..ee11eabbd 100644 --- a/tdeioslave/info/info.cc +++ b/tdeioslave/info/info.cc @@ -26,8 +26,8 @@ InfoProtocol::InfoProtocol( const TQCString &pool, const TQCString &app ) kdDebug( 7108 ) << "InfoProtocol::InfoProtocol" << endl; m_perl = TDEGlobal::dirs()->findExe( "perl" ); - m_infoScript = locate( "data", "kio_info/kde-info2html" ); - m_infoConf = locate("data", "kio_info/kde-info2html.conf"); + m_infoScript = locate( "data", "tdeio_info/kde-info2html" ); + m_infoConf = locate("data", "tdeio_info/kde-info2html.conf"); if( m_perl.isNull() || m_infoScript.isNull() || m_infoConf.isNull() ) { kdError( 7108 ) << "Critical error: Cannot locate files for HTML-conversion" << endl; @@ -35,7 +35,7 @@ InfoProtocol::InfoProtocol( const TQCString &pool, const TQCString &app ) if ( m_perl.isNull() ) { errorStr = "perl."; } else { - TQString missing =m_infoScript.isNull() ? "kio_info/kde-info2html" : "kio_info/kde-info2html.conf"; + TQString missing =m_infoScript.isNull() ? "tdeio_info/kde-info2html" : "tdeio_info/kde-info2html.conf"; errorStr = "kde-info2html" + i18n( "\nUnable to locate file %1 which is necessary to run this service. " "Please check your software installation" ).arg( missing ); } @@ -244,13 +244,13 @@ extern "C" { int KDE_EXPORT kdemain( int argc, char **argv ); } int kdemain( int argc, char **argv ) { - TDEInstance instance( "kio_info" ); + TDEInstance instance( "tdeio_info" ); - kdDebug() << "kio_info starting " << getpid() << endl; + kdDebug() << "tdeio_info starting " << getpid() << endl; if (argc != 4) { - fprintf(stderr, "Usage: kio_info protocol domain-socket1 domain-socket2\n"); + fprintf(stderr, "Usage: tdeio_info protocol domain-socket1 domain-socket2\n"); exit(-1); } diff --git a/tdeioslave/info/info.protocol b/tdeioslave/info/info.protocol index 491511ed2..fc8db0dfa 100644 --- a/tdeioslave/info/info.protocol +++ b/tdeioslave/info/info.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_info +exec=tdeio_info protocol=info input=none output=filesystem diff --git a/tdeioslave/ldap/CMakeLists.txt b/tdeioslave/ldap/CMakeLists.txt index ebf162205..d05048e0d 100644 --- a/tdeioslave/ldap/CMakeLists.txt +++ b/tdeioslave/ldap/CMakeLists.txt @@ -28,10 +28,10 @@ link_directories( install( FILES ldap.protocol ldaps.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_ldap (module) ######################### +##### tdeio_ldap (module) ######################### -tde_add_kpart( kio_ldap AUTOMOC - SOURCES kio_ldap.cpp +tde_add_kpart( tdeio_ldap AUTOMOC + SOURCES tdeio_ldap.cpp LINK kabc-shared ${LDAP_LIBRARIES} DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/ldap/Makefile.am b/tdeioslave/ldap/Makefile.am index ca66e1b17..3f71b669b 100644 --- a/tdeioslave/ldap/Makefile.am +++ b/tdeioslave/ldap/Makefile.am @@ -7,13 +7,13 @@ LDADD = $(LIB_KIO) $(LDAP_LIBS) ####### Files -kde_module_LTLIBRARIES = kio_ldap.la +kde_module_LTLIBRARIES = tdeio_ldap.la -kio_ldap_la_SOURCES = kio_ldap.cpp -kio_ldap_la_LIBADD = $(LIB_KIO) $(LDAP_LIBS) $(LIB_KABC) -kio_ldap_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LDAP_RPATH) -module $(KDE_PLUGIN) +tdeio_ldap_la_SOURCES = tdeio_ldap.cpp +tdeio_ldap_la_LIBADD = $(LIB_KIO) $(LDAP_LIBS) $(LIB_KABC) +tdeio_ldap_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LDAP_RPATH) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_ldap.h +noinst_HEADERS = tdeio_ldap.h kdelnk_DATA = ldap.protocol ldaps.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/ldap/kio_ldap.cpp b/tdeioslave/ldap/kio_ldap.cpp deleted file mode 100644 index d4a29f1d4..000000000 --- a/tdeioslave/ldap/kio_ldap.cpp +++ /dev/null @@ -1,1154 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef HAVE_SASL_SASL_H //prefer libsasl2 -#include -#else -#ifdef HAVE_SASL_H -#include -#endif -#endif -#include - -#include "kio_ldap.h" - -using namespace TDEIO; -using namespace KABC; - -extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } - -/** - * The main program. - */ -int kdemain( int argc, char **argv ) -{ - TDEInstance instance( "kio_ldap" ); - - kdDebug(7125) << "Starting " << getpid() << endl; - - if ( argc != 4 ) { - kdError() << "Usage kio_ldap protocol pool app" << endl; - return -1; - } - - // let the protocol class do its work - LDAPProtocol slave( argv[1], argv[ 2 ], argv[ 3 ] ); - slave.dispatchLoop(); - - kdDebug( 7125 ) << "Done" << endl; - return 0; -} - -/** - * Initialize the ldap slave - */ -LDAPProtocol::LDAPProtocol( const TQCString &protocol, const TQCString &pool, - const TQCString &app ) : SlaveBase( protocol, pool, app ) -{ - mLDAP = 0; mTLS = 0; mVer = 3; mAuthSASL = false; - mRealm = ""; mBindName = ""; - mTimeLimit = mSizeLimit = 0; - kdDebug(7125) << "LDAPProtocol::LDAPProtocol (" << protocol << ")" << endl; -} - -LDAPProtocol::~LDAPProtocol() -{ - closeConnection(); -} - -void LDAPProtocol::LDAPErr( const KURL &url, int err ) -{ - - char *errmsg = 0; - if ( mLDAP ) { - if ( err == LDAP_SUCCESS ) ldap_get_option( mLDAP, LDAP_OPT_ERROR_NUMBER, &err ); - if ( err != LDAP_SUCCESS ) ldap_get_option( mLDAP, LDAP_OPT_ERROR_STRING, &errmsg ); - } - if ( err == LDAP_SUCCESS ) return; - kdDebug(7125) << "error code: " << err << " msg: " << ldap_err2string(err) << - " Additonal error message: '" << errmsg << "'" << endl; - TQString msg; - TQString extraMsg; - if ( errmsg ) { - if ( errmsg[0] ) - extraMsg = i18n("\nAdditional info: ") + TQString::fromUtf8( errmsg ); - free( errmsg ); - } - msg = url.prettyURL(); - if ( !extraMsg.isEmpty() ) msg += extraMsg; - - /* FIXME: No need to close on all errors */ - closeConnection(); - - switch (err) { -/* FIXME: is it worth mapping the following error codes to kio errors? - - LDAP_OPERATIONS_ERROR - LDAP_STRONG_AUTH_REQUIRED - LDAP_PROTOCOL_ERROR - LDAP_TIMELIMIT_EXCEEDED - LDAP_SIZELIMIT_EXCEEDED - LDAP_COMPARE_FALSE - LDAP_COMPARE_TRUE - LDAP_PARTIAL_RESULTS - LDAP_NO_SUCH_ATTRIBUTE - LDAP_UNDEFINED_TYPE - LDAP_INAPPROPRIATE_MATCHING - LDAP_CONSTRAINT_VIOLATION - LDAP_INVALID_SYNTAX - LDAP_NO_SUCH_OBJECT - LDAP_ALIAS_PROBLEM - LDAP_INVALID_DN_SYNTAX - LDAP_IS_LEAF - LDAP_ALIAS_DEREF_PROBLEM - LDAP_INAPPROPRIATE_AUTH - LDAP_BUSY - LDAP_UNAVAILABLE - LDAP_UNWILLING_TO_PERFORM - LDAP_LOOP_DETECT - LDAP_NAMING_VIOLATION - LDAP_OBJECT_CLASS_VIOLATION - LDAP_NOT_ALLOWED_ON_NONLEAF - LDAP_NOT_ALLOWED_ON_RDN - LDAP_NO_OBJECT_CLASS_MODS - LDAP_OTHER - LDAP_LOCAL_ERROR - LDAP_ENCODING_ERROR - LDAP_DECODING_ERROR - LDAP_FILTER_ERROR -*/ - case LDAP_AUTH_UNKNOWN: - case LDAP_INVALID_CREDENTIALS: - case LDAP_STRONG_AUTH_NOT_SUPPORTED: - error(ERR_COULD_NOT_AUTHENTICATE, msg); - break; - case LDAP_ALREADY_EXISTS: - error(ERR_FILE_ALREADY_EXIST, msg); - break; - case LDAP_INSUFFICIENT_ACCESS: - error(ERR_ACCESS_DENIED, msg); - break; - case LDAP_CONNECT_ERROR: - case LDAP_SERVER_DOWN: - error(ERR_COULD_NOT_CONNECT,msg); - break; - case LDAP_TIMEOUT: - error(ERR_SERVER_TIMEOUT,msg); - break; - case LDAP_PARAM_ERROR: - error(ERR_INTERNAL,msg); - break; - case LDAP_NO_MEMORY: - error(ERR_OUT_OF_MEMORY,msg); - break; - - default: - error( ERR_SLAVE_DEFINED, - i18n( "LDAP server returned the error: %1 %2\nThe LDAP URL was: %3" ). - arg( ldap_err2string(err)).arg( extraMsg ).arg( url.prettyURL() ) ); - } -} - -void LDAPProtocol::controlsFromMetaData( LDAPControl ***serverctrls, - LDAPControl ***clientctrls ) -{ - TQString oid; bool critical; TQByteArray value; - int i = 0; - while ( hasMetaData( TQString::fromLatin1("SERVER_CTRL%1").arg(i) ) ) { - TQCString val = metaData( TQString::fromLatin1("SERVER_CTRL%1").arg(i) ).utf8(); - LDIF::splitControl( val, oid, critical, value ); - kdDebug(7125) << "server ctrl #" << i << " value: " << val << - " oid: " << oid << " critical: " << critical << " value: " << - TQString(TQString::fromUtf8( value, value.size() )) << endl; - addControlOp( serverctrls, oid, value, critical ); - i++; - } - i = 0; - while ( hasMetaData( TQString::fromLatin1("CLIENT_CTRL%1").arg(i) ) ) { - TQCString val = metaData( TQString::fromLatin1("CLIENT_CTRL%1").arg(i) ).utf8(); - LDIF::splitControl( val, oid, critical, value ); - kdDebug(7125) << "client ctrl #" << i << " value: " << val << - " oid: " << oid << " critical: " << critical << " value: " << - TQString(TQString::fromUtf8( value, value.size() )) << endl; - addControlOp( clientctrls, oid, value, critical ); - i++; - } -} - -int LDAPProtocol::asyncSearch( LDAPUrl &usrc ) -{ - char **attrs = 0; - int msgid; - LDAPControl **serverctrls = 0, **clientctrls = 0; - - int count = usrc.attributes().count(); - if ( count > 0 ) { - attrs = static_cast( malloc((count+1) * sizeof(char*)) ); - for (int i=0; ibv_val; - unsigned long len = bvals[i]->bv_len; - tmp.setRawData( val, len ); - result += LDIF::assembleLine( TQString::fromUtf8( name ), tmp, 76 ) + '\n'; - tmp.resetRawData( val, len ); - } - ldap_value_free_len(bvals); - } - ldap_memfree( name ); - // next attribute - name = ldap_next_attribute(mLDAP, message, entry); - } - return result; -} - -void LDAPProtocol::addControlOp( LDAPControl ***pctrls, const TQString &oid, - const TQByteArray &value, bool critical ) -{ - LDAPControl **ctrls; - LDAPControl *ctrl = (LDAPControl *) malloc( sizeof( LDAPControl ) ); - - ctrls = *pctrls; - - kdDebug(7125) << "addControlOp: oid:'" << oid << "' val: '" << - TQString(TQString::fromUtf8(value, value.size())) << "'" << endl; - int vallen = value.size(); - ctrl->ldctl_value.bv_len = vallen; - if ( vallen ) { - ctrl->ldctl_value.bv_val = (char*) malloc( vallen ); - memcpy( ctrl->ldctl_value.bv_val, value.data(), vallen ); - } else { - ctrl->ldctl_value.bv_val = 0; - } - ctrl->ldctl_iscritical = critical; - ctrl->ldctl_oid = strdup( oid.utf8() ); - - uint i = 0; - - if ( ctrls == 0 ) { - ctrls = (LDAPControl **) malloc ( 2 * sizeof( LDAPControl* ) ); - ctrls[ 0 ] = 0; - ctrls[ 1 ] = 0; - } else { - while ( ctrls[ i ] != 0 ) i++; - ctrls[ i + 1 ] = 0; - ctrls = (LDAPControl **) realloc( ctrls, (i + 2) * sizeof( LDAPControl * ) ); - } - ctrls[ i ] = ctrl; - - *pctrls = ctrls; -} - -void LDAPProtocol::addModOp( LDAPMod ***pmods, int mod_type, const TQString &attr, - const TQByteArray &value ) -{ -// kdDebug(7125) << "type: " << mod_type << " attr: " << attr << -// " value: " << TQString::fromUtf8(value,value.size()) << -// " size: " << value.size() << endl; - LDAPMod **mods; - - mods = *pmods; - - uint i = 0; - - if ( mods == 0 ) { - mods = (LDAPMod **) malloc ( 2 * sizeof( LDAPMod* ) ); - mods[ 0 ] = (LDAPMod*) malloc( sizeof( LDAPMod ) ); - mods[ 1 ] = 0; - memset( mods[ 0 ], 0, sizeof( LDAPMod ) ); - } else { - while( mods[ i ] != 0 && - ( strcmp( attr.utf8(),mods[i]->mod_type ) != 0 || - ( mods[ i ]->mod_op & ~LDAP_MOD_BVALUES ) != mod_type ) ) i++; - - if ( mods[ i ] == 0 ) { - mods = ( LDAPMod ** )realloc( mods, (i + 2) * sizeof( LDAPMod * ) ); - if ( mods == 0 ) { - kdError() << "addModOp: realloc" << endl; - return; - } - mods[ i + 1 ] = 0; - mods[ i ] = ( LDAPMod* ) malloc( sizeof( LDAPMod ) ); - memset( mods[ i ], 0, sizeof( LDAPMod ) ); - } - } - - mods[ i ]->mod_op = mod_type | LDAP_MOD_BVALUES; - if ( mods[ i ]->mod_type == 0 ) mods[ i ]->mod_type = strdup( attr.utf8() ); - - *pmods = mods; - - int vallen = value.size(); - if ( vallen == 0 ) return; - BerValue *berval; - berval = ( BerValue* ) malloc( sizeof( BerValue ) ); - berval -> bv_val = (char*) malloc( vallen ); - berval -> bv_len = vallen; - memcpy( berval -> bv_val, value.data(), vallen ); - - if ( mods[ i ] -> mod_vals.modv_bvals == 0 ) { - mods[ i ]->mod_vals.modv_bvals = ( BerValue** ) malloc( sizeof( BerValue* ) * 2 ); - mods[ i ]->mod_vals.modv_bvals[ 0 ] = berval; - mods[ i ]->mod_vals.modv_bvals[ 1 ] = 0; - kdDebug(7125) << "addModOp: new bervalue struct " << endl; - } else { - uint j = 0; - while ( mods[ i ]->mod_vals.modv_bvals[ j ] != 0 ) j++; - mods[ i ]->mod_vals.modv_bvals = ( BerValue ** ) - realloc( mods[ i ]->mod_vals.modv_bvals, (j + 2) * sizeof( BerValue* ) ); - if ( mods[ i ]->mod_vals.modv_bvals == 0 ) { - kdError() << "addModOp: realloc" << endl; - return; - } - mods[ i ]->mod_vals.modv_bvals[ j ] = berval; - mods[ i ]->mod_vals.modv_bvals[ j+1 ] = 0; - kdDebug(7125) << j << ". new bervalue " << endl; - } -} - -void LDAPProtocol::LDAPEntry2UDSEntry( const TQString &dn, UDSEntry &entry, - const LDAPUrl &usrc, bool dir ) -{ - UDSAtom atom; - - int pos; - entry.clear(); - atom.m_uds = UDS_NAME; - atom.m_long = 0; - TQString name = dn; - if ( (pos = name.find(",")) > 0 ) - name = name.left( pos ); - if ( (pos = name.find("=")) > 0 ) - name.remove( 0, pos+1 ); - name.replace(' ', "_"); - if ( !dir ) name += ".ldif"; - atom.m_str = name; - entry.append( atom ); - - // the file type - atom.m_uds = UDS_FILE_TYPE; - atom.m_str = ""; - atom.m_long = dir ? S_IFDIR : S_IFREG; - entry.append( atom ); - - // the mimetype - if (!dir) { - atom.m_uds = UDS_MIME_TYPE; - atom.m_long = 0; - atom.m_str = "text/plain"; - entry.append( atom ); - } - - atom.m_uds = UDS_ACCESS; - atom.m_long = dir ? 0500 : 0400; - entry.append( atom ); - - // the url - atom.m_uds = UDS_URL; - atom.m_long = 0; - LDAPUrl url; - url=usrc; - - url.setPath("/"+dn); - url.setScope( dir ? LDAPUrl::One : LDAPUrl::Base ); - atom.m_str = url.prettyURL(); - entry.append( atom ); -} - -void LDAPProtocol::changeCheck( LDAPUrl &url ) -{ - bool critical; - bool tls = ( url.hasExtension( "x-tls" ) ); - int ver = 3; - if ( url.hasExtension( "x-ver" ) ) - ver = url.extension( "x-ver", critical).toInt(); - bool authSASL = url.hasExtension( "x-sasl" ); - TQString mech; - if ( url.hasExtension( "x-mech" ) ) - mech = url.extension( "x-mech", critical).upper(); - TQString realm; - if ( url.hasExtension( "x-realm" ) ) - mech = url.extension( "x-realm", critical).upper(); - TQString bindname; - if ( url.hasExtension( "bindname" ) ) - bindname = url.extension( "bindname", critical).upper(); - int timelimit = 0; - if ( url.hasExtension( "x-timelimit" ) ) - timelimit = url.extension( "x-timelimit", critical).toInt(); - int sizelimit = 0; - if ( url.hasExtension( "x-sizelimit" ) ) - sizelimit = url.extension( "x-sizelimit", critical).toInt(); - - if ( !authSASL && bindname.isEmpty() ) bindname = mUser; - - if ( tls != mTLS || ver != mVer || authSASL != mAuthSASL || mech != mMech || - mRealm != realm || mBindName != bindname || mTimeLimit != timelimit || - mSizeLimit != sizelimit ) { - closeConnection(); - mTLS = tls; - mVer = ver; - mAuthSASL = authSASL; - mMech = mech; - mRealm = realm; - mBindName = bindname; - mTimeLimit = timelimit; - mSizeLimit = sizelimit; - kdDebug(7125) << "parameters changed: tls = " << mTLS << - " version: " << mVer << "SASLauth: " << mAuthSASL << endl; - openConnection(); - if ( mAuthSASL ) { - url.setUser( mUser ); - } else { - url.setUser( mBindName ); - } - } else { - if ( !mLDAP ) openConnection(); - } -} - -void LDAPProtocol::setHost( const TQString& host, int port, - const TQString& user, const TQString& password ) -{ - - if( mHost != host || mPort != port || mUser != user || mPassword != password ) - closeConnection(); - - mHost = host; - if( port > 0 ) - mPort = port; - else { - struct servent *pse; - if ( (pse = getservbyname(mProtocol, "tcp")) == NULL ) - if ( mProtocol == "ldaps" ) - mPort = 636; - else - mPort = 389; - else - mPort = ntohs( pse->s_port ); - } - mUser = user; - mPassword = password; - - kdDebug(7125) << "setHost: " << host << " port: " << port << " user: " << - mUser << " pass: [protected]" << endl; -} - -static int kldap_sasl_interact( LDAP *, unsigned, void *slave, void *in ) -{ - return ((LDAPProtocol*) slave)->saslInteract( in ); -} - -void LDAPProtocol::fillAuthInfo( AuthInfo &info ) -{ - info.url.setProtocol( mProtocol ); - info.url.setHost( mHost ); - info.url.setPort( mPort ); - info.url.setUser( mUser ); - info.caption = i18n("LDAP Login"); - info.comment = TQString::fromLatin1( mProtocol ) + "://" + mHost + ":" + - TQString::number( mPort ); - info.commentLabel = i18n("site:"); - info.username = mAuthSASL ? mUser : mBindName; - info.password = mPassword; - info.keepPassword = true; -} - -int LDAPProtocol::saslInteract( void *in ) -{ -#if defined HAVE_SASL_H || defined HAVE_SASL_SASL_H - AuthInfo info; - fillAuthInfo( info ); - - sasl_interact_t *interact = ( sasl_interact_t * ) in; - - //some mechanisms do not require username && pass, so it doesn't need a popup - //window for getting this info - for ( ; interact->id != SASL_CB_LIST_END; interact++ ) { - if ( interact->id == SASL_CB_AUTHNAME || - interact->id == SASL_CB_PASS ) { - - if ( info.username.isEmpty() || info.password.isEmpty() ) { - - const bool cached = checkCachedAuthentication( info ); - - if ( ! ( ( mFirstAuth && cached ) || - ( mFirstAuth ? - openPassDlg( info ) : - openPassDlg( info, i18n("Invalid authorization information.") ) ) ) ) { - kdDebug(7125) << "Dialog cancelled!" << endl; - mCancel = true; - return LDAP_USER_CANCELLED; - } - mUser = info.username; - mPassword = info.password; - } - break; - } - } - - interact = ( sasl_interact_t * ) in; - TQString value; - - while( interact->id != SASL_CB_LIST_END ) { - value = ""; - switch( interact->id ) { - case SASL_CB_GETREALM: - value = mRealm; - kdDebug(7125) << "SASL_REALM=" << mRealm << endl; - break; - case SASL_CB_AUTHNAME: - value = mUser; - kdDebug(7125) << "SASL_AUTHNAME=" << mUser << endl; - break; - case SASL_CB_PASS: - value = mPassword; - kdDebug(7125) << "SASL_PASSWD=[hidden]" << endl; - break; - case SASL_CB_USER: - value = mBindName; - kdDebug(7125) << "SASL_AUTHZID=" << mBindName << endl; - break; - } - if ( value.isEmpty() ) { - interact->result = NULL; - interact->len = 0; - } else { - interact->result = strdup( value.utf8() ); - interact->len = strlen( (const char *) interact->result ); - } - interact++; - } - -#endif - return LDAP_SUCCESS; -} - -void LDAPProtocol::openConnection() -{ - if ( mLDAP ) return; - - int version,ret; - - version = ( mVer == 2 ) ? LDAP_VERSION2 : LDAP_VERSION3; - - KURL Url; - Url.setProtocol( mProtocol ); - Url.setHost( mHost ); - Url.setPort( mPort ); - - AuthInfo info; - fillAuthInfo( info ); -/////////////////////////////////////////////////////////////////////////// - kdDebug(7125) << "OpenConnection to " << mHost << ":" << mPort << endl; - - ret = ldap_initialize( &mLDAP, Url.htmlURL().utf8() ); - if ( ret != LDAP_SUCCESS ) { - LDAPErr( Url, ret ); - return; - } - - if ( (ldap_set_option( mLDAP, LDAP_OPT_PROTOCOL_VERSION, &version )) != - LDAP_OPT_SUCCESS ) { - - closeConnection(); - error( ERR_UNSUPPORTED_ACTION, - i18n("Cannot set LDAP protocol version %1").arg(version) ); - return; - } - - if ( mTLS ) { - kdDebug(7125) << "start TLS" << endl; - if ( ( ret = ldap_start_tls_s( mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) { - LDAPErr( Url ); - return; - } - } - - if ( mSizeLimit ) { - kdDebug(7125) << "sizelimit: " << mSizeLimit << endl; - if ( ldap_set_option( mLDAP, LDAP_OPT_SIZELIMIT, &mSizeLimit ) != LDAP_SUCCESS ) { - closeConnection(); - error( ERR_UNSUPPORTED_ACTION, - i18n("Cannot set size limit.")); - return; - } - } - - if ( mTimeLimit ) { - kdDebug(7125) << "timelimit: " << mTimeLimit << endl; - if ( ldap_set_option( mLDAP, LDAP_OPT_TIMELIMIT, &mTimeLimit ) != LDAP_SUCCESS ) { - closeConnection(); - error( ERR_UNSUPPORTED_ACTION, - i18n("Cannot set time limit.")); - return; - } - } - -#if !defined HAVE_SASL_H && !defined HAVE_SASL_SASL_H - if ( mAuthSASL ) { - closeConnection(); - error( ERR_SLAVE_DEFINED, - i18n("SASL authentication not compiled into the ldap ioslave.") ); - return; - } -#endif - - bool auth = false; - TQString mechanism = mMech.isEmpty() ? "DIGEST-MD5" : mMech; - mFirstAuth = true; mCancel = false; - - const bool cached = checkCachedAuthentication( info ); - - ret = LDAP_SUCCESS; - while (!auth) { - if ( !mAuthSASL && ( - ( mFirstAuth && - !( mBindName.isEmpty() && mPassword.isEmpty() ) && //For anonymous bind - ( mBindName.isEmpty() || mPassword.isEmpty() ) ) || !mFirstAuth ) ) - { - if ( ( mFirstAuth && cached ) || - ( mFirstAuth ? - openPassDlg( info ) : - openPassDlg( info, i18n("Invalid authorization information.") ) ) ) { - - mBindName = info.username; - mPassword = info.password; - } else { - kdDebug(7125) << "Dialog cancelled!" << endl; - error( ERR_USER_CANCELED, TQString::null ); - closeConnection(); - return; - } - } - kdDebug(7125) << "user: " << mUser << " bindname: " << mBindName << endl; - ret = -#if defined HAVE_SASL_H || defined HAVE_SASL_SASL_H - mAuthSASL ? - ldap_sasl_interactive_bind_s( mLDAP, NULL, mechanism.utf8(), - NULL, NULL, LDAP_SASL_INTERACTIVE, &kldap_sasl_interact, this ) : -#endif - ldap_simple_bind_s( mLDAP, mBindName.utf8(), mPassword.utf8() ); - - mFirstAuth = false; - if ( ret != LDAP_INVALID_CREDENTIALS && - ret != LDAP_INSUFFICIENT_ACCESS && - ret != LDAP_INAPPROPRIATE_AUTH ) { - kdDebug(7125) << "ldap_bind retval: " << ret << endl; - auth = true; - if ( ret != LDAP_SUCCESS ) { - if ( mCancel ) - error( ERR_USER_CANCELED, TQString::null ); - else - LDAPErr( Url ); - closeConnection(); - return; - } - } - } - - kdDebug(7125) << "connected!" << endl; - connected(); -} - -void LDAPProtocol::closeConnection() -{ - if (mLDAP) ldap_unbind(mLDAP); - mLDAP = 0; - kdDebug(7125) << "connection closed!" << endl; -} - -/** - * Get the information contained in the URL. - */ -void LDAPProtocol::get( const KURL &_url ) -{ - kdDebug(7125) << "get(" << _url << ")" << endl; - - LDAPUrl usrc(_url); - int ret, id; - LDAPMessage *msg,*entry; - - changeCheck( usrc ); - if ( !mLDAP ) { - finished(); - return; - } - - if ( (id = asyncSearch( usrc )) == -1 ) { - LDAPErr( _url ); - return; - } - - // tell the mimetype - mimeType("text/plain"); - // collect the result - TQCString result; - filesize_t processed_size = 0; - TQByteArray array; - - while( true ) { - ret = ldap_result( mLDAP, id, 0, NULL, &msg ); - if ( ret == -1 ) { - LDAPErr( _url ); - return; - } - kdDebug(7125) << " ldap_result: " << ret << endl; - if ( ret == LDAP_RES_SEARCH_RESULT ) break; - if ( ret != LDAP_RES_SEARCH_ENTRY ) continue; - - entry = ldap_first_entry( mLDAP, msg ); - while ( entry ) { - result = LDAPEntryAsLDIF(entry); - result += '\n'; - uint len = result.length(); - processed_size += len; - array.setRawData( result.data(), len ); - data(array); - processedSize( processed_size ); - array.resetRawData( result.data(), len ); - - entry = ldap_next_entry( mLDAP, entry ); - } - LDAPErr( _url ); - - ldap_msgfree(msg); - // tell the length - } - - totalSize(processed_size); - - array.resize(0); - // tell we are finished - data(array); - - // tell we are finished - finished(); -} - -/** - * Test if the url contains a directory or a file. - */ -void LDAPProtocol::stat( const KURL &_url ) -{ - kdDebug(7125) << "stat(" << _url << ")" << endl; - - TQStringList att,saveatt; - LDAPUrl usrc(_url); - LDAPMessage *msg; - int ret, id; - - changeCheck( usrc ); - if ( !mLDAP ) { - finished(); - return; - } - - // look how many entries match - saveatt = usrc.attributes(); - att.append( "dn" ); - usrc.setAttributes( att ); - if ( _url.query().isEmpty() ) usrc.setScope( LDAPUrl::One ); - - if ( (id = asyncSearch( usrc )) == -1 ) { - LDAPErr( _url ); - return; - } - - kdDebug(7125) << "stat() getting result" << endl; - do { - ret = ldap_result( mLDAP, id, 0, NULL, &msg ); - if ( ret == -1 ) { - LDAPErr( _url ); - return; - } - if ( ret == LDAP_RES_SEARCH_RESULT ) { - ldap_msgfree( msg ); - error( ERR_DOES_NOT_EXIST, _url.prettyURL() ); - return; - } - } while ( ret != LDAP_RES_SEARCH_ENTRY ); - - ldap_msgfree( msg ); - ldap_abandon( mLDAP, id ); - - usrc.setAttributes( saveatt ); - - UDSEntry uds; - bool critical; - LDAPEntry2UDSEntry( usrc.dn(), uds, usrc, usrc.extension("x-dir", critical) != "base" ); - - statEntry( uds ); - // we are done - finished(); -} - -/** - * Deletes one entry; - */ -void LDAPProtocol::del( const KURL &_url, bool ) -{ - kdDebug(7125) << "del(" << _url << ")" << endl; - - LDAPUrl usrc(_url); - int ret; - - changeCheck( usrc ); - if ( !mLDAP ) { - finished(); - return; - } - - kdDebug(7125) << " del: " << usrc.dn().utf8() << endl ; - - if ( (ret = ldap_delete_s( mLDAP,usrc.dn().utf8() )) != LDAP_SUCCESS ) { - LDAPErr( _url ); - return; - } - finished(); -} - -#define FREELDAPMEM { \ - ldap_mods_free( lmod, 1 ); \ - ldap_controls_free( serverctrls ); \ - ldap_controls_free( clientctrls ); \ - lmod = 0; serverctrls = 0; clientctrls = 0; \ - } - -void LDAPProtocol::put( const KURL &_url, int, bool overwrite, bool ) -{ - kdDebug(7125) << "put(" << _url << ")" << endl; - - LDAPUrl usrc(_url); - - changeCheck( usrc ); - if ( !mLDAP ) { - finished(); - return; - } - - LDAPMod **lmod = 0; - LDAPControl **serverctrls = 0, **clientctrls = 0; - TQByteArray buffer; - int result = 0; - LDIF::ParseVal ret; - LDIF ldif; - ret = LDIF::MoreData; - int ldaperr; - - - do { - if ( ret == LDIF::MoreData ) { - dataReq(); // Request for data - result = readData( buffer ); - ldif.setLDIF( buffer ); - } - if ( result < 0 ) { - //error - FREELDAPMEM; - return; - } - if ( result == 0 ) { - kdDebug(7125) << "EOF!" << endl; - ldif.endLDIF(); - } - do { - - ret = ldif.nextItem(); - kdDebug(7125) << "nextitem: " << ret << endl; - - switch ( ret ) { - case LDIF::None: - case LDIF::NewEntry: - case LDIF::MoreData: - break; - case LDIF::EndEntry: - ldaperr = LDAP_SUCCESS; - switch ( ldif.entryType() ) { - case LDIF::Entry_None: - error( ERR_INTERNAL, i18n("The LDIF parser failed.") ); - FREELDAPMEM; - return; - case LDIF::Entry_Del: - kdDebug(7125) << "kio_ldap_del" << endl; - controlsFromMetaData( &serverctrls, &clientctrls ); - ldaperr = ldap_delete_ext_s( mLDAP, ldif.dn().utf8(), - serverctrls, clientctrls ); - FREELDAPMEM; - break; - case LDIF::Entry_Modrdn: - kdDebug(7125) << "kio_ldap_modrdn olddn:" << ldif.dn() << - " newRdn: " << ldif.newRdn() << - " newSuperior: " << ldif.newSuperior() << - " deloldrdn: " << ldif.delOldRdn() << endl; - controlsFromMetaData( &serverctrls, &clientctrls ); - ldaperr = ldap_rename_s( mLDAP, ldif.dn().utf8(), ldif.newRdn().utf8(), - ldif.newSuperior().isEmpty() ? TQCString() : ldif.newSuperior().utf8(), - ldif.delOldRdn(), serverctrls, clientctrls ); - - FREELDAPMEM; - break; - case LDIF::Entry_Mod: - kdDebug(7125) << "kio_ldap_mod" << endl; - if ( lmod ) { - controlsFromMetaData( &serverctrls, &clientctrls ); - ldaperr = ldap_modify_ext_s( mLDAP, ldif.dn().utf8(), lmod, - serverctrls, clientctrls ); - FREELDAPMEM; - } - break; - case LDIF::Entry_Add: - kdDebug(7125) << "kio_ldap_add " << ldif.dn() << endl; - if ( lmod ) { - controlsFromMetaData( &serverctrls, &clientctrls ); - ldaperr = ldap_add_ext_s( mLDAP, ldif.dn().utf8(), lmod, - serverctrls, clientctrls ); - if ( ldaperr == LDAP_ALREADY_EXISTS && overwrite ) { - kdDebug(7125) << ldif.dn() << " already exists, delete first" << endl; - ldaperr = ldap_delete_s( mLDAP, ldif.dn().utf8() ); - if ( ldaperr == LDAP_SUCCESS ) - ldaperr = ldap_add_ext_s( mLDAP, ldif.dn().utf8(), lmod, - serverctrls, clientctrls ); - } - FREELDAPMEM; - } - break; - } - if ( ldaperr != LDAP_SUCCESS ) { - kdDebug(7125) << "put ldap error: " << ldap_err2string(ldaperr) << endl; - LDAPErr( _url ); - FREELDAPMEM; - return; - } - break; - case LDIF::Item: - switch ( ldif.entryType() ) { - case LDIF::Entry_Mod: { - int modtype = 0; - switch ( ldif.modType() ) { - case LDIF::Mod_None: - modtype = 0; - break; - case LDIF::Mod_Add: - modtype = LDAP_MOD_ADD; - break; - case LDIF::Mod_Replace: - modtype = LDAP_MOD_REPLACE; - break; - case LDIF::Mod_Del: - modtype = LDAP_MOD_DELETE; - break; - } - addModOp( &lmod, modtype, ldif.attr(), ldif.val() ); - break; - } - case LDIF::Entry_Add: - if ( ldif.val().size() > 0 ) - addModOp( &lmod, 0, ldif.attr(), ldif.val() ); - break; - default: - error( ERR_INTERNAL, i18n("The LDIF parser failed.") ); - FREELDAPMEM; - return; - } - break; - case LDIF::Control: - addControlOp( &serverctrls, ldif.oid(), ldif.val(), ldif.critical() ); - break; - case LDIF::Err: - error( ERR_SLAVE_DEFINED, - i18n( "Invalid LDIF file in line %1." ).arg( ldif.lineNo() ) ); - FREELDAPMEM; - return; - } - } while ( ret != LDIF::MoreData ); - } while ( result > 0 ); - - FREELDAPMEM; - finished(); -} - -/** - * List the contents of a directory. - */ -void LDAPProtocol::listDir( const KURL &_url ) -{ - int ret, ret2, id, id2; - unsigned long total=0; - char *dn; - TQStringList att,saveatt; - LDAPMessage *entry,*msg,*entry2,*msg2; - LDAPUrl usrc(_url),usrc2; - bool critical; - bool isSub = ( usrc.extension( "x-dir", critical ) == "sub" ); - - kdDebug(7125) << "listDir(" << _url << ")" << endl; - - changeCheck( usrc ); - if ( !mLDAP ) { - finished(); - return; - } - usrc2 = usrc; - - saveatt = usrc.attributes(); - // look up the entries - if ( isSub ) { - att.append("dn"); - usrc.setAttributes(att); - } - if ( _url.query().isEmpty() ) usrc.setScope( LDAPUrl::One ); - - if ( (id = asyncSearch( usrc )) == -1 ) { - LDAPErr( _url ); - return; - } - - usrc.setAttributes( "" ); - usrc.setExtension( "x-dir", "base" ); - // publish the results - UDSEntry uds; - - while( true ) { - ret = ldap_result( mLDAP, id, 0, NULL, &msg ); - if ( ret == -1 ) { - LDAPErr( _url ); - return; - } - if ( ret == LDAP_RES_SEARCH_RESULT ) break; - if ( ret != LDAP_RES_SEARCH_ENTRY ) continue; - kdDebug(7125) << " ldap_result: " << ret << endl; - - entry = ldap_first_entry( mLDAP, msg ); - while( entry ) { - - total++; - uds.clear(); - - dn = ldap_get_dn( mLDAP, entry ); - kdDebug(7125) << "dn: " << dn << endl; - LDAPEntry2UDSEntry( TQString::fromUtf8(dn), uds, usrc ); - listEntry( uds, false ); -// processedSize( total ); - kdDebug(7125) << " total: " << total << " " << usrc.prettyURL() << endl; - - // publish the sub-directories (if dirmode==sub) - if ( isSub ) { - usrc2.setDn( TQString::fromUtf8( dn ) ); - usrc2.setScope( LDAPUrl::One ); - usrc2.setAttributes( att ); - usrc2.setFilter( TQString::null ); - kdDebug(7125) << "search2 " << dn << endl; - if ( (id2 = asyncSearch( usrc2 )) != -1 ) { - while ( true ) { - kdDebug(7125) << " next result " << endl; - ret2 = ldap_result( mLDAP, id2, 0, NULL, &msg2 ); - if ( ret2 == -1 ) break; - if ( ret2 == LDAP_RES_SEARCH_RESULT ) { - ldap_msgfree( msg2 ); - break; - } - if ( ret2 == LDAP_RES_SEARCH_ENTRY ) { - entry2=ldap_first_entry( mLDAP, msg2 ); - if ( entry2 ) { - usrc2.setAttributes( saveatt ); - usrc2.setFilter( usrc.filter() ); - LDAPEntry2UDSEntry( TQString::fromUtf8( dn ), uds, usrc2, true ); - listEntry( uds, false ); - total++; - } - ldap_msgfree( msg2 ); - ldap_abandon( mLDAP, id2 ); - break; - } - } - } - } - free( dn ); - - entry = ldap_next_entry( mLDAP, entry ); - } - LDAPErr( _url ); - ldap_msgfree( msg ); - } - -// totalSize( total ); - - uds.clear(); - listEntry( uds, true ); - // we are done - finished(); -} diff --git a/tdeioslave/ldap/kio_ldap.h b/tdeioslave/ldap/kio_ldap.h deleted file mode 100644 index f3bd61fe5..000000000 --- a/tdeioslave/ldap/kio_ldap.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __LDAP_H__ -#define __LDAP_H__ - -#include -#include - -#include -#include - -#define LDAP_DEPRECATED 1 /* Needed for ldap_simple_bind_s with openldap >= 2.3.x */ -#include -#include -#include - -class LDAPProtocol : public TDEIO::SlaveBase -{ - public: - LDAPProtocol( const TQCString &protocol, const TQCString &pool, const TQCString &app ); - virtual ~LDAPProtocol(); - - virtual void setHost( const TQString& host, int port, - const TQString& user, const TQString& pass ); - - virtual void openConnection(); - virtual void closeConnection(); - - virtual void get( const KURL& url ); - virtual void stat( const KURL& url ); - virtual void listDir( const KURL& url ); - virtual void del( const KURL& url, bool isfile ); - virtual void put( const KURL& url, int permissions, bool overwrite, bool resume ); - - int saslInteract( void *in ); - - private: - - TQString mHost; - int mPort; - TQString mUser; - TQString mPassword; - LDAP *mLDAP; - int mVer, mSizeLimit, mTimeLimit; - bool mTLS; - bool mAuthSASL; - TQString mMech,mRealm,mBindName; - bool mCancel, mFirstAuth; - - void controlsFromMetaData( LDAPControl ***serverctrls, - LDAPControl ***clientctrls ); - void addControlOp( LDAPControl ***pctrls, const TQString &oid, - const TQByteArray &value, bool critical ); - void addModOp( LDAPMod ***pmods, int mod_type, - const TQString &attr, const TQByteArray &value ); - void LDAPEntry2UDSEntry( const TQString &dn, TDEIO::UDSEntry &entry, - const KABC::LDAPUrl &usrc, bool dir=false ); - int asyncSearch( KABC::LDAPUrl &usrc ); - - TQCString LDAPEntryAsLDIF( LDAPMessage *msg ); - void LDAPErr( const KURL &url, int err = LDAP_SUCCESS ); - void changeCheck( KABC::LDAPUrl &url ); - - void fillAuthInfo( TDEIO::AuthInfo &info ); -}; - -#endif diff --git a/tdeioslave/ldap/ldap.protocol b/tdeioslave/ldap/ldap.protocol index 3e1e77b4b..3082c6cb7 100644 --- a/tdeioslave/ldap/ldap.protocol +++ b/tdeioslave/ldap/ldap.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_ldap +exec=tdeio_ldap protocol=ldap input=none output=filesystem diff --git a/tdeioslave/ldap/ldaps.protocol b/tdeioslave/ldap/ldaps.protocol index 1dd927506..2bcb2234c 100644 --- a/tdeioslave/ldap/ldaps.protocol +++ b/tdeioslave/ldap/ldaps.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_ldap +exec=tdeio_ldap protocol=ldaps input=none output=filesystem diff --git a/tdeioslave/ldap/tdeio_ldap.cpp b/tdeioslave/ldap/tdeio_ldap.cpp new file mode 100644 index 000000000..2e22e6994 --- /dev/null +++ b/tdeioslave/ldap/tdeio_ldap.cpp @@ -0,0 +1,1154 @@ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_SASL_SASL_H //prefer libsasl2 +#include +#else +#ifdef HAVE_SASL_H +#include +#endif +#endif +#include + +#include "tdeio_ldap.h" + +using namespace TDEIO; +using namespace KABC; + +extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } + +/** + * The main program. + */ +int kdemain( int argc, char **argv ) +{ + TDEInstance instance( "tdeio_ldap" ); + + kdDebug(7125) << "Starting " << getpid() << endl; + + if ( argc != 4 ) { + kdError() << "Usage tdeio_ldap protocol pool app" << endl; + return -1; + } + + // let the protocol class do its work + LDAPProtocol slave( argv[1], argv[ 2 ], argv[ 3 ] ); + slave.dispatchLoop(); + + kdDebug( 7125 ) << "Done" << endl; + return 0; +} + +/** + * Initialize the ldap slave + */ +LDAPProtocol::LDAPProtocol( const TQCString &protocol, const TQCString &pool, + const TQCString &app ) : SlaveBase( protocol, pool, app ) +{ + mLDAP = 0; mTLS = 0; mVer = 3; mAuthSASL = false; + mRealm = ""; mBindName = ""; + mTimeLimit = mSizeLimit = 0; + kdDebug(7125) << "LDAPProtocol::LDAPProtocol (" << protocol << ")" << endl; +} + +LDAPProtocol::~LDAPProtocol() +{ + closeConnection(); +} + +void LDAPProtocol::LDAPErr( const KURL &url, int err ) +{ + + char *errmsg = 0; + if ( mLDAP ) { + if ( err == LDAP_SUCCESS ) ldap_get_option( mLDAP, LDAP_OPT_ERROR_NUMBER, &err ); + if ( err != LDAP_SUCCESS ) ldap_get_option( mLDAP, LDAP_OPT_ERROR_STRING, &errmsg ); + } + if ( err == LDAP_SUCCESS ) return; + kdDebug(7125) << "error code: " << err << " msg: " << ldap_err2string(err) << + " Additonal error message: '" << errmsg << "'" << endl; + TQString msg; + TQString extraMsg; + if ( errmsg ) { + if ( errmsg[0] ) + extraMsg = i18n("\nAdditional info: ") + TQString::fromUtf8( errmsg ); + free( errmsg ); + } + msg = url.prettyURL(); + if ( !extraMsg.isEmpty() ) msg += extraMsg; + + /* FIXME: No need to close on all errors */ + closeConnection(); + + switch (err) { +/* FIXME: is it worth mapping the following error codes to tdeio errors? + + LDAP_OPERATIONS_ERROR + LDAP_STRONG_AUTH_REQUIRED + LDAP_PROTOCOL_ERROR + LDAP_TIMELIMIT_EXCEEDED + LDAP_SIZELIMIT_EXCEEDED + LDAP_COMPARE_FALSE + LDAP_COMPARE_TRUE + LDAP_PARTIAL_RESULTS + LDAP_NO_SUCH_ATTRIBUTE + LDAP_UNDEFINED_TYPE + LDAP_INAPPROPRIATE_MATCHING + LDAP_CONSTRAINT_VIOLATION + LDAP_INVALID_SYNTAX + LDAP_NO_SUCH_OBJECT + LDAP_ALIAS_PROBLEM + LDAP_INVALID_DN_SYNTAX + LDAP_IS_LEAF + LDAP_ALIAS_DEREF_PROBLEM + LDAP_INAPPROPRIATE_AUTH + LDAP_BUSY + LDAP_UNAVAILABLE + LDAP_UNWILLING_TO_PERFORM + LDAP_LOOP_DETECT + LDAP_NAMING_VIOLATION + LDAP_OBJECT_CLASS_VIOLATION + LDAP_NOT_ALLOWED_ON_NONLEAF + LDAP_NOT_ALLOWED_ON_RDN + LDAP_NO_OBJECT_CLASS_MODS + LDAP_OTHER + LDAP_LOCAL_ERROR + LDAP_ENCODING_ERROR + LDAP_DECODING_ERROR + LDAP_FILTER_ERROR +*/ + case LDAP_AUTH_UNKNOWN: + case LDAP_INVALID_CREDENTIALS: + case LDAP_STRONG_AUTH_NOT_SUPPORTED: + error(ERR_COULD_NOT_AUTHENTICATE, msg); + break; + case LDAP_ALREADY_EXISTS: + error(ERR_FILE_ALREADY_EXIST, msg); + break; + case LDAP_INSUFFICIENT_ACCESS: + error(ERR_ACCESS_DENIED, msg); + break; + case LDAP_CONNECT_ERROR: + case LDAP_SERVER_DOWN: + error(ERR_COULD_NOT_CONNECT,msg); + break; + case LDAP_TIMEOUT: + error(ERR_SERVER_TIMEOUT,msg); + break; + case LDAP_PARAM_ERROR: + error(ERR_INTERNAL,msg); + break; + case LDAP_NO_MEMORY: + error(ERR_OUT_OF_MEMORY,msg); + break; + + default: + error( ERR_SLAVE_DEFINED, + i18n( "LDAP server returned the error: %1 %2\nThe LDAP URL was: %3" ). + arg( ldap_err2string(err)).arg( extraMsg ).arg( url.prettyURL() ) ); + } +} + +void LDAPProtocol::controlsFromMetaData( LDAPControl ***serverctrls, + LDAPControl ***clientctrls ) +{ + TQString oid; bool critical; TQByteArray value; + int i = 0; + while ( hasMetaData( TQString::fromLatin1("SERVER_CTRL%1").arg(i) ) ) { + TQCString val = metaData( TQString::fromLatin1("SERVER_CTRL%1").arg(i) ).utf8(); + LDIF::splitControl( val, oid, critical, value ); + kdDebug(7125) << "server ctrl #" << i << " value: " << val << + " oid: " << oid << " critical: " << critical << " value: " << + TQString(TQString::fromUtf8( value, value.size() )) << endl; + addControlOp( serverctrls, oid, value, critical ); + i++; + } + i = 0; + while ( hasMetaData( TQString::fromLatin1("CLIENT_CTRL%1").arg(i) ) ) { + TQCString val = metaData( TQString::fromLatin1("CLIENT_CTRL%1").arg(i) ).utf8(); + LDIF::splitControl( val, oid, critical, value ); + kdDebug(7125) << "client ctrl #" << i << " value: " << val << + " oid: " << oid << " critical: " << critical << " value: " << + TQString(TQString::fromUtf8( value, value.size() )) << endl; + addControlOp( clientctrls, oid, value, critical ); + i++; + } +} + +int LDAPProtocol::asyncSearch( LDAPUrl &usrc ) +{ + char **attrs = 0; + int msgid; + LDAPControl **serverctrls = 0, **clientctrls = 0; + + int count = usrc.attributes().count(); + if ( count > 0 ) { + attrs = static_cast( malloc((count+1) * sizeof(char*)) ); + for (int i=0; ibv_val; + unsigned long len = bvals[i]->bv_len; + tmp.setRawData( val, len ); + result += LDIF::assembleLine( TQString::fromUtf8( name ), tmp, 76 ) + '\n'; + tmp.resetRawData( val, len ); + } + ldap_value_free_len(bvals); + } + ldap_memfree( name ); + // next attribute + name = ldap_next_attribute(mLDAP, message, entry); + } + return result; +} + +void LDAPProtocol::addControlOp( LDAPControl ***pctrls, const TQString &oid, + const TQByteArray &value, bool critical ) +{ + LDAPControl **ctrls; + LDAPControl *ctrl = (LDAPControl *) malloc( sizeof( LDAPControl ) ); + + ctrls = *pctrls; + + kdDebug(7125) << "addControlOp: oid:'" << oid << "' val: '" << + TQString(TQString::fromUtf8(value, value.size())) << "'" << endl; + int vallen = value.size(); + ctrl->ldctl_value.bv_len = vallen; + if ( vallen ) { + ctrl->ldctl_value.bv_val = (char*) malloc( vallen ); + memcpy( ctrl->ldctl_value.bv_val, value.data(), vallen ); + } else { + ctrl->ldctl_value.bv_val = 0; + } + ctrl->ldctl_iscritical = critical; + ctrl->ldctl_oid = strdup( oid.utf8() ); + + uint i = 0; + + if ( ctrls == 0 ) { + ctrls = (LDAPControl **) malloc ( 2 * sizeof( LDAPControl* ) ); + ctrls[ 0 ] = 0; + ctrls[ 1 ] = 0; + } else { + while ( ctrls[ i ] != 0 ) i++; + ctrls[ i + 1 ] = 0; + ctrls = (LDAPControl **) realloc( ctrls, (i + 2) * sizeof( LDAPControl * ) ); + } + ctrls[ i ] = ctrl; + + *pctrls = ctrls; +} + +void LDAPProtocol::addModOp( LDAPMod ***pmods, int mod_type, const TQString &attr, + const TQByteArray &value ) +{ +// kdDebug(7125) << "type: " << mod_type << " attr: " << attr << +// " value: " << TQString::fromUtf8(value,value.size()) << +// " size: " << value.size() << endl; + LDAPMod **mods; + + mods = *pmods; + + uint i = 0; + + if ( mods == 0 ) { + mods = (LDAPMod **) malloc ( 2 * sizeof( LDAPMod* ) ); + mods[ 0 ] = (LDAPMod*) malloc( sizeof( LDAPMod ) ); + mods[ 1 ] = 0; + memset( mods[ 0 ], 0, sizeof( LDAPMod ) ); + } else { + while( mods[ i ] != 0 && + ( strcmp( attr.utf8(),mods[i]->mod_type ) != 0 || + ( mods[ i ]->mod_op & ~LDAP_MOD_BVALUES ) != mod_type ) ) i++; + + if ( mods[ i ] == 0 ) { + mods = ( LDAPMod ** )realloc( mods, (i + 2) * sizeof( LDAPMod * ) ); + if ( mods == 0 ) { + kdError() << "addModOp: realloc" << endl; + return; + } + mods[ i + 1 ] = 0; + mods[ i ] = ( LDAPMod* ) malloc( sizeof( LDAPMod ) ); + memset( mods[ i ], 0, sizeof( LDAPMod ) ); + } + } + + mods[ i ]->mod_op = mod_type | LDAP_MOD_BVALUES; + if ( mods[ i ]->mod_type == 0 ) mods[ i ]->mod_type = strdup( attr.utf8() ); + + *pmods = mods; + + int vallen = value.size(); + if ( vallen == 0 ) return; + BerValue *berval; + berval = ( BerValue* ) malloc( sizeof( BerValue ) ); + berval -> bv_val = (char*) malloc( vallen ); + berval -> bv_len = vallen; + memcpy( berval -> bv_val, value.data(), vallen ); + + if ( mods[ i ] -> mod_vals.modv_bvals == 0 ) { + mods[ i ]->mod_vals.modv_bvals = ( BerValue** ) malloc( sizeof( BerValue* ) * 2 ); + mods[ i ]->mod_vals.modv_bvals[ 0 ] = berval; + mods[ i ]->mod_vals.modv_bvals[ 1 ] = 0; + kdDebug(7125) << "addModOp: new bervalue struct " << endl; + } else { + uint j = 0; + while ( mods[ i ]->mod_vals.modv_bvals[ j ] != 0 ) j++; + mods[ i ]->mod_vals.modv_bvals = ( BerValue ** ) + realloc( mods[ i ]->mod_vals.modv_bvals, (j + 2) * sizeof( BerValue* ) ); + if ( mods[ i ]->mod_vals.modv_bvals == 0 ) { + kdError() << "addModOp: realloc" << endl; + return; + } + mods[ i ]->mod_vals.modv_bvals[ j ] = berval; + mods[ i ]->mod_vals.modv_bvals[ j+1 ] = 0; + kdDebug(7125) << j << ". new bervalue " << endl; + } +} + +void LDAPProtocol::LDAPEntry2UDSEntry( const TQString &dn, UDSEntry &entry, + const LDAPUrl &usrc, bool dir ) +{ + UDSAtom atom; + + int pos; + entry.clear(); + atom.m_uds = UDS_NAME; + atom.m_long = 0; + TQString name = dn; + if ( (pos = name.find(",")) > 0 ) + name = name.left( pos ); + if ( (pos = name.find("=")) > 0 ) + name.remove( 0, pos+1 ); + name.replace(' ', "_"); + if ( !dir ) name += ".ldif"; + atom.m_str = name; + entry.append( atom ); + + // the file type + atom.m_uds = UDS_FILE_TYPE; + atom.m_str = ""; + atom.m_long = dir ? S_IFDIR : S_IFREG; + entry.append( atom ); + + // the mimetype + if (!dir) { + atom.m_uds = UDS_MIME_TYPE; + atom.m_long = 0; + atom.m_str = "text/plain"; + entry.append( atom ); + } + + atom.m_uds = UDS_ACCESS; + atom.m_long = dir ? 0500 : 0400; + entry.append( atom ); + + // the url + atom.m_uds = UDS_URL; + atom.m_long = 0; + LDAPUrl url; + url=usrc; + + url.setPath("/"+dn); + url.setScope( dir ? LDAPUrl::One : LDAPUrl::Base ); + atom.m_str = url.prettyURL(); + entry.append( atom ); +} + +void LDAPProtocol::changeCheck( LDAPUrl &url ) +{ + bool critical; + bool tls = ( url.hasExtension( "x-tls" ) ); + int ver = 3; + if ( url.hasExtension( "x-ver" ) ) + ver = url.extension( "x-ver", critical).toInt(); + bool authSASL = url.hasExtension( "x-sasl" ); + TQString mech; + if ( url.hasExtension( "x-mech" ) ) + mech = url.extension( "x-mech", critical).upper(); + TQString realm; + if ( url.hasExtension( "x-realm" ) ) + mech = url.extension( "x-realm", critical).upper(); + TQString bindname; + if ( url.hasExtension( "bindname" ) ) + bindname = url.extension( "bindname", critical).upper(); + int timelimit = 0; + if ( url.hasExtension( "x-timelimit" ) ) + timelimit = url.extension( "x-timelimit", critical).toInt(); + int sizelimit = 0; + if ( url.hasExtension( "x-sizelimit" ) ) + sizelimit = url.extension( "x-sizelimit", critical).toInt(); + + if ( !authSASL && bindname.isEmpty() ) bindname = mUser; + + if ( tls != mTLS || ver != mVer || authSASL != mAuthSASL || mech != mMech || + mRealm != realm || mBindName != bindname || mTimeLimit != timelimit || + mSizeLimit != sizelimit ) { + closeConnection(); + mTLS = tls; + mVer = ver; + mAuthSASL = authSASL; + mMech = mech; + mRealm = realm; + mBindName = bindname; + mTimeLimit = timelimit; + mSizeLimit = sizelimit; + kdDebug(7125) << "parameters changed: tls = " << mTLS << + " version: " << mVer << "SASLauth: " << mAuthSASL << endl; + openConnection(); + if ( mAuthSASL ) { + url.setUser( mUser ); + } else { + url.setUser( mBindName ); + } + } else { + if ( !mLDAP ) openConnection(); + } +} + +void LDAPProtocol::setHost( const TQString& host, int port, + const TQString& user, const TQString& password ) +{ + + if( mHost != host || mPort != port || mUser != user || mPassword != password ) + closeConnection(); + + mHost = host; + if( port > 0 ) + mPort = port; + else { + struct servent *pse; + if ( (pse = getservbyname(mProtocol, "tcp")) == NULL ) + if ( mProtocol == "ldaps" ) + mPort = 636; + else + mPort = 389; + else + mPort = ntohs( pse->s_port ); + } + mUser = user; + mPassword = password; + + kdDebug(7125) << "setHost: " << host << " port: " << port << " user: " << + mUser << " pass: [protected]" << endl; +} + +static int kldap_sasl_interact( LDAP *, unsigned, void *slave, void *in ) +{ + return ((LDAPProtocol*) slave)->saslInteract( in ); +} + +void LDAPProtocol::fillAuthInfo( AuthInfo &info ) +{ + info.url.setProtocol( mProtocol ); + info.url.setHost( mHost ); + info.url.setPort( mPort ); + info.url.setUser( mUser ); + info.caption = i18n("LDAP Login"); + info.comment = TQString::fromLatin1( mProtocol ) + "://" + mHost + ":" + + TQString::number( mPort ); + info.commentLabel = i18n("site:"); + info.username = mAuthSASL ? mUser : mBindName; + info.password = mPassword; + info.keepPassword = true; +} + +int LDAPProtocol::saslInteract( void *in ) +{ +#if defined HAVE_SASL_H || defined HAVE_SASL_SASL_H + AuthInfo info; + fillAuthInfo( info ); + + sasl_interact_t *interact = ( sasl_interact_t * ) in; + + //some mechanisms do not require username && pass, so it doesn't need a popup + //window for getting this info + for ( ; interact->id != SASL_CB_LIST_END; interact++ ) { + if ( interact->id == SASL_CB_AUTHNAME || + interact->id == SASL_CB_PASS ) { + + if ( info.username.isEmpty() || info.password.isEmpty() ) { + + const bool cached = checkCachedAuthentication( info ); + + if ( ! ( ( mFirstAuth && cached ) || + ( mFirstAuth ? + openPassDlg( info ) : + openPassDlg( info, i18n("Invalid authorization information.") ) ) ) ) { + kdDebug(7125) << "Dialog cancelled!" << endl; + mCancel = true; + return LDAP_USER_CANCELLED; + } + mUser = info.username; + mPassword = info.password; + } + break; + } + } + + interact = ( sasl_interact_t * ) in; + TQString value; + + while( interact->id != SASL_CB_LIST_END ) { + value = ""; + switch( interact->id ) { + case SASL_CB_GETREALM: + value = mRealm; + kdDebug(7125) << "SASL_REALM=" << mRealm << endl; + break; + case SASL_CB_AUTHNAME: + value = mUser; + kdDebug(7125) << "SASL_AUTHNAME=" << mUser << endl; + break; + case SASL_CB_PASS: + value = mPassword; + kdDebug(7125) << "SASL_PASSWD=[hidden]" << endl; + break; + case SASL_CB_USER: + value = mBindName; + kdDebug(7125) << "SASL_AUTHZID=" << mBindName << endl; + break; + } + if ( value.isEmpty() ) { + interact->result = NULL; + interact->len = 0; + } else { + interact->result = strdup( value.utf8() ); + interact->len = strlen( (const char *) interact->result ); + } + interact++; + } + +#endif + return LDAP_SUCCESS; +} + +void LDAPProtocol::openConnection() +{ + if ( mLDAP ) return; + + int version,ret; + + version = ( mVer == 2 ) ? LDAP_VERSION2 : LDAP_VERSION3; + + KURL Url; + Url.setProtocol( mProtocol ); + Url.setHost( mHost ); + Url.setPort( mPort ); + + AuthInfo info; + fillAuthInfo( info ); +/////////////////////////////////////////////////////////////////////////// + kdDebug(7125) << "OpenConnection to " << mHost << ":" << mPort << endl; + + ret = ldap_initialize( &mLDAP, Url.htmlURL().utf8() ); + if ( ret != LDAP_SUCCESS ) { + LDAPErr( Url, ret ); + return; + } + + if ( (ldap_set_option( mLDAP, LDAP_OPT_PROTOCOL_VERSION, &version )) != + LDAP_OPT_SUCCESS ) { + + closeConnection(); + error( ERR_UNSUPPORTED_ACTION, + i18n("Cannot set LDAP protocol version %1").arg(version) ); + return; + } + + if ( mTLS ) { + kdDebug(7125) << "start TLS" << endl; + if ( ( ret = ldap_start_tls_s( mLDAP, NULL, NULL ) ) != LDAP_SUCCESS ) { + LDAPErr( Url ); + return; + } + } + + if ( mSizeLimit ) { + kdDebug(7125) << "sizelimit: " << mSizeLimit << endl; + if ( ldap_set_option( mLDAP, LDAP_OPT_SIZELIMIT, &mSizeLimit ) != LDAP_SUCCESS ) { + closeConnection(); + error( ERR_UNSUPPORTED_ACTION, + i18n("Cannot set size limit.")); + return; + } + } + + if ( mTimeLimit ) { + kdDebug(7125) << "timelimit: " << mTimeLimit << endl; + if ( ldap_set_option( mLDAP, LDAP_OPT_TIMELIMIT, &mTimeLimit ) != LDAP_SUCCESS ) { + closeConnection(); + error( ERR_UNSUPPORTED_ACTION, + i18n("Cannot set time limit.")); + return; + } + } + +#if !defined HAVE_SASL_H && !defined HAVE_SASL_SASL_H + if ( mAuthSASL ) { + closeConnection(); + error( ERR_SLAVE_DEFINED, + i18n("SASL authentication not compiled into the ldap ioslave.") ); + return; + } +#endif + + bool auth = false; + TQString mechanism = mMech.isEmpty() ? "DIGEST-MD5" : mMech; + mFirstAuth = true; mCancel = false; + + const bool cached = checkCachedAuthentication( info ); + + ret = LDAP_SUCCESS; + while (!auth) { + if ( !mAuthSASL && ( + ( mFirstAuth && + !( mBindName.isEmpty() && mPassword.isEmpty() ) && //For anonymous bind + ( mBindName.isEmpty() || mPassword.isEmpty() ) ) || !mFirstAuth ) ) + { + if ( ( mFirstAuth && cached ) || + ( mFirstAuth ? + openPassDlg( info ) : + openPassDlg( info, i18n("Invalid authorization information.") ) ) ) { + + mBindName = info.username; + mPassword = info.password; + } else { + kdDebug(7125) << "Dialog cancelled!" << endl; + error( ERR_USER_CANCELED, TQString::null ); + closeConnection(); + return; + } + } + kdDebug(7125) << "user: " << mUser << " bindname: " << mBindName << endl; + ret = +#if defined HAVE_SASL_H || defined HAVE_SASL_SASL_H + mAuthSASL ? + ldap_sasl_interactive_bind_s( mLDAP, NULL, mechanism.utf8(), + NULL, NULL, LDAP_SASL_INTERACTIVE, &kldap_sasl_interact, this ) : +#endif + ldap_simple_bind_s( mLDAP, mBindName.utf8(), mPassword.utf8() ); + + mFirstAuth = false; + if ( ret != LDAP_INVALID_CREDENTIALS && + ret != LDAP_INSUFFICIENT_ACCESS && + ret != LDAP_INAPPROPRIATE_AUTH ) { + kdDebug(7125) << "ldap_bind retval: " << ret << endl; + auth = true; + if ( ret != LDAP_SUCCESS ) { + if ( mCancel ) + error( ERR_USER_CANCELED, TQString::null ); + else + LDAPErr( Url ); + closeConnection(); + return; + } + } + } + + kdDebug(7125) << "connected!" << endl; + connected(); +} + +void LDAPProtocol::closeConnection() +{ + if (mLDAP) ldap_unbind(mLDAP); + mLDAP = 0; + kdDebug(7125) << "connection closed!" << endl; +} + +/** + * Get the information contained in the URL. + */ +void LDAPProtocol::get( const KURL &_url ) +{ + kdDebug(7125) << "get(" << _url << ")" << endl; + + LDAPUrl usrc(_url); + int ret, id; + LDAPMessage *msg,*entry; + + changeCheck( usrc ); + if ( !mLDAP ) { + finished(); + return; + } + + if ( (id = asyncSearch( usrc )) == -1 ) { + LDAPErr( _url ); + return; + } + + // tell the mimetype + mimeType("text/plain"); + // collect the result + TQCString result; + filesize_t processed_size = 0; + TQByteArray array; + + while( true ) { + ret = ldap_result( mLDAP, id, 0, NULL, &msg ); + if ( ret == -1 ) { + LDAPErr( _url ); + return; + } + kdDebug(7125) << " ldap_result: " << ret << endl; + if ( ret == LDAP_RES_SEARCH_RESULT ) break; + if ( ret != LDAP_RES_SEARCH_ENTRY ) continue; + + entry = ldap_first_entry( mLDAP, msg ); + while ( entry ) { + result = LDAPEntryAsLDIF(entry); + result += '\n'; + uint len = result.length(); + processed_size += len; + array.setRawData( result.data(), len ); + data(array); + processedSize( processed_size ); + array.resetRawData( result.data(), len ); + + entry = ldap_next_entry( mLDAP, entry ); + } + LDAPErr( _url ); + + ldap_msgfree(msg); + // tell the length + } + + totalSize(processed_size); + + array.resize(0); + // tell we are finished + data(array); + + // tell we are finished + finished(); +} + +/** + * Test if the url contains a directory or a file. + */ +void LDAPProtocol::stat( const KURL &_url ) +{ + kdDebug(7125) << "stat(" << _url << ")" << endl; + + TQStringList att,saveatt; + LDAPUrl usrc(_url); + LDAPMessage *msg; + int ret, id; + + changeCheck( usrc ); + if ( !mLDAP ) { + finished(); + return; + } + + // look how many entries match + saveatt = usrc.attributes(); + att.append( "dn" ); + usrc.setAttributes( att ); + if ( _url.query().isEmpty() ) usrc.setScope( LDAPUrl::One ); + + if ( (id = asyncSearch( usrc )) == -1 ) { + LDAPErr( _url ); + return; + } + + kdDebug(7125) << "stat() getting result" << endl; + do { + ret = ldap_result( mLDAP, id, 0, NULL, &msg ); + if ( ret == -1 ) { + LDAPErr( _url ); + return; + } + if ( ret == LDAP_RES_SEARCH_RESULT ) { + ldap_msgfree( msg ); + error( ERR_DOES_NOT_EXIST, _url.prettyURL() ); + return; + } + } while ( ret != LDAP_RES_SEARCH_ENTRY ); + + ldap_msgfree( msg ); + ldap_abandon( mLDAP, id ); + + usrc.setAttributes( saveatt ); + + UDSEntry uds; + bool critical; + LDAPEntry2UDSEntry( usrc.dn(), uds, usrc, usrc.extension("x-dir", critical) != "base" ); + + statEntry( uds ); + // we are done + finished(); +} + +/** + * Deletes one entry; + */ +void LDAPProtocol::del( const KURL &_url, bool ) +{ + kdDebug(7125) << "del(" << _url << ")" << endl; + + LDAPUrl usrc(_url); + int ret; + + changeCheck( usrc ); + if ( !mLDAP ) { + finished(); + return; + } + + kdDebug(7125) << " del: " << usrc.dn().utf8() << endl ; + + if ( (ret = ldap_delete_s( mLDAP,usrc.dn().utf8() )) != LDAP_SUCCESS ) { + LDAPErr( _url ); + return; + } + finished(); +} + +#define FREELDAPMEM { \ + ldap_mods_free( lmod, 1 ); \ + ldap_controls_free( serverctrls ); \ + ldap_controls_free( clientctrls ); \ + lmod = 0; serverctrls = 0; clientctrls = 0; \ + } + +void LDAPProtocol::put( const KURL &_url, int, bool overwrite, bool ) +{ + kdDebug(7125) << "put(" << _url << ")" << endl; + + LDAPUrl usrc(_url); + + changeCheck( usrc ); + if ( !mLDAP ) { + finished(); + return; + } + + LDAPMod **lmod = 0; + LDAPControl **serverctrls = 0, **clientctrls = 0; + TQByteArray buffer; + int result = 0; + LDIF::ParseVal ret; + LDIF ldif; + ret = LDIF::MoreData; + int ldaperr; + + + do { + if ( ret == LDIF::MoreData ) { + dataReq(); // Request for data + result = readData( buffer ); + ldif.setLDIF( buffer ); + } + if ( result < 0 ) { + //error + FREELDAPMEM; + return; + } + if ( result == 0 ) { + kdDebug(7125) << "EOF!" << endl; + ldif.endLDIF(); + } + do { + + ret = ldif.nextItem(); + kdDebug(7125) << "nextitem: " << ret << endl; + + switch ( ret ) { + case LDIF::None: + case LDIF::NewEntry: + case LDIF::MoreData: + break; + case LDIF::EndEntry: + ldaperr = LDAP_SUCCESS; + switch ( ldif.entryType() ) { + case LDIF::Entry_None: + error( ERR_INTERNAL, i18n("The LDIF parser failed.") ); + FREELDAPMEM; + return; + case LDIF::Entry_Del: + kdDebug(7125) << "tdeio_ldap_del" << endl; + controlsFromMetaData( &serverctrls, &clientctrls ); + ldaperr = ldap_delete_ext_s( mLDAP, ldif.dn().utf8(), + serverctrls, clientctrls ); + FREELDAPMEM; + break; + case LDIF::Entry_Modrdn: + kdDebug(7125) << "tdeio_ldap_modrdn olddn:" << ldif.dn() << + " newRdn: " << ldif.newRdn() << + " newSuperior: " << ldif.newSuperior() << + " deloldrdn: " << ldif.delOldRdn() << endl; + controlsFromMetaData( &serverctrls, &clientctrls ); + ldaperr = ldap_rename_s( mLDAP, ldif.dn().utf8(), ldif.newRdn().utf8(), + ldif.newSuperior().isEmpty() ? TQCString() : ldif.newSuperior().utf8(), + ldif.delOldRdn(), serverctrls, clientctrls ); + + FREELDAPMEM; + break; + case LDIF::Entry_Mod: + kdDebug(7125) << "tdeio_ldap_mod" << endl; + if ( lmod ) { + controlsFromMetaData( &serverctrls, &clientctrls ); + ldaperr = ldap_modify_ext_s( mLDAP, ldif.dn().utf8(), lmod, + serverctrls, clientctrls ); + FREELDAPMEM; + } + break; + case LDIF::Entry_Add: + kdDebug(7125) << "tdeio_ldap_add " << ldif.dn() << endl; + if ( lmod ) { + controlsFromMetaData( &serverctrls, &clientctrls ); + ldaperr = ldap_add_ext_s( mLDAP, ldif.dn().utf8(), lmod, + serverctrls, clientctrls ); + if ( ldaperr == LDAP_ALREADY_EXISTS && overwrite ) { + kdDebug(7125) << ldif.dn() << " already exists, delete first" << endl; + ldaperr = ldap_delete_s( mLDAP, ldif.dn().utf8() ); + if ( ldaperr == LDAP_SUCCESS ) + ldaperr = ldap_add_ext_s( mLDAP, ldif.dn().utf8(), lmod, + serverctrls, clientctrls ); + } + FREELDAPMEM; + } + break; + } + if ( ldaperr != LDAP_SUCCESS ) { + kdDebug(7125) << "put ldap error: " << ldap_err2string(ldaperr) << endl; + LDAPErr( _url ); + FREELDAPMEM; + return; + } + break; + case LDIF::Item: + switch ( ldif.entryType() ) { + case LDIF::Entry_Mod: { + int modtype = 0; + switch ( ldif.modType() ) { + case LDIF::Mod_None: + modtype = 0; + break; + case LDIF::Mod_Add: + modtype = LDAP_MOD_ADD; + break; + case LDIF::Mod_Replace: + modtype = LDAP_MOD_REPLACE; + break; + case LDIF::Mod_Del: + modtype = LDAP_MOD_DELETE; + break; + } + addModOp( &lmod, modtype, ldif.attr(), ldif.val() ); + break; + } + case LDIF::Entry_Add: + if ( ldif.val().size() > 0 ) + addModOp( &lmod, 0, ldif.attr(), ldif.val() ); + break; + default: + error( ERR_INTERNAL, i18n("The LDIF parser failed.") ); + FREELDAPMEM; + return; + } + break; + case LDIF::Control: + addControlOp( &serverctrls, ldif.oid(), ldif.val(), ldif.critical() ); + break; + case LDIF::Err: + error( ERR_SLAVE_DEFINED, + i18n( "Invalid LDIF file in line %1." ).arg( ldif.lineNo() ) ); + FREELDAPMEM; + return; + } + } while ( ret != LDIF::MoreData ); + } while ( result > 0 ); + + FREELDAPMEM; + finished(); +} + +/** + * List the contents of a directory. + */ +void LDAPProtocol::listDir( const KURL &_url ) +{ + int ret, ret2, id, id2; + unsigned long total=0; + char *dn; + TQStringList att,saveatt; + LDAPMessage *entry,*msg,*entry2,*msg2; + LDAPUrl usrc(_url),usrc2; + bool critical; + bool isSub = ( usrc.extension( "x-dir", critical ) == "sub" ); + + kdDebug(7125) << "listDir(" << _url << ")" << endl; + + changeCheck( usrc ); + if ( !mLDAP ) { + finished(); + return; + } + usrc2 = usrc; + + saveatt = usrc.attributes(); + // look up the entries + if ( isSub ) { + att.append("dn"); + usrc.setAttributes(att); + } + if ( _url.query().isEmpty() ) usrc.setScope( LDAPUrl::One ); + + if ( (id = asyncSearch( usrc )) == -1 ) { + LDAPErr( _url ); + return; + } + + usrc.setAttributes( "" ); + usrc.setExtension( "x-dir", "base" ); + // publish the results + UDSEntry uds; + + while( true ) { + ret = ldap_result( mLDAP, id, 0, NULL, &msg ); + if ( ret == -1 ) { + LDAPErr( _url ); + return; + } + if ( ret == LDAP_RES_SEARCH_RESULT ) break; + if ( ret != LDAP_RES_SEARCH_ENTRY ) continue; + kdDebug(7125) << " ldap_result: " << ret << endl; + + entry = ldap_first_entry( mLDAP, msg ); + while( entry ) { + + total++; + uds.clear(); + + dn = ldap_get_dn( mLDAP, entry ); + kdDebug(7125) << "dn: " << dn << endl; + LDAPEntry2UDSEntry( TQString::fromUtf8(dn), uds, usrc ); + listEntry( uds, false ); +// processedSize( total ); + kdDebug(7125) << " total: " << total << " " << usrc.prettyURL() << endl; + + // publish the sub-directories (if dirmode==sub) + if ( isSub ) { + usrc2.setDn( TQString::fromUtf8( dn ) ); + usrc2.setScope( LDAPUrl::One ); + usrc2.setAttributes( att ); + usrc2.setFilter( TQString::null ); + kdDebug(7125) << "search2 " << dn << endl; + if ( (id2 = asyncSearch( usrc2 )) != -1 ) { + while ( true ) { + kdDebug(7125) << " next result " << endl; + ret2 = ldap_result( mLDAP, id2, 0, NULL, &msg2 ); + if ( ret2 == -1 ) break; + if ( ret2 == LDAP_RES_SEARCH_RESULT ) { + ldap_msgfree( msg2 ); + break; + } + if ( ret2 == LDAP_RES_SEARCH_ENTRY ) { + entry2=ldap_first_entry( mLDAP, msg2 ); + if ( entry2 ) { + usrc2.setAttributes( saveatt ); + usrc2.setFilter( usrc.filter() ); + LDAPEntry2UDSEntry( TQString::fromUtf8( dn ), uds, usrc2, true ); + listEntry( uds, false ); + total++; + } + ldap_msgfree( msg2 ); + ldap_abandon( mLDAP, id2 ); + break; + } + } + } + } + free( dn ); + + entry = ldap_next_entry( mLDAP, entry ); + } + LDAPErr( _url ); + ldap_msgfree( msg ); + } + +// totalSize( total ); + + uds.clear(); + listEntry( uds, true ); + // we are done + finished(); +} diff --git a/tdeioslave/ldap/tdeio_ldap.h b/tdeioslave/ldap/tdeio_ldap.h new file mode 100644 index 000000000..f3bd61fe5 --- /dev/null +++ b/tdeioslave/ldap/tdeio_ldap.h @@ -0,0 +1,65 @@ +#ifndef __LDAP_H__ +#define __LDAP_H__ + +#include +#include + +#include +#include + +#define LDAP_DEPRECATED 1 /* Needed for ldap_simple_bind_s with openldap >= 2.3.x */ +#include +#include +#include + +class LDAPProtocol : public TDEIO::SlaveBase +{ + public: + LDAPProtocol( const TQCString &protocol, const TQCString &pool, const TQCString &app ); + virtual ~LDAPProtocol(); + + virtual void setHost( const TQString& host, int port, + const TQString& user, const TQString& pass ); + + virtual void openConnection(); + virtual void closeConnection(); + + virtual void get( const KURL& url ); + virtual void stat( const KURL& url ); + virtual void listDir( const KURL& url ); + virtual void del( const KURL& url, bool isfile ); + virtual void put( const KURL& url, int permissions, bool overwrite, bool resume ); + + int saslInteract( void *in ); + + private: + + TQString mHost; + int mPort; + TQString mUser; + TQString mPassword; + LDAP *mLDAP; + int mVer, mSizeLimit, mTimeLimit; + bool mTLS; + bool mAuthSASL; + TQString mMech,mRealm,mBindName; + bool mCancel, mFirstAuth; + + void controlsFromMetaData( LDAPControl ***serverctrls, + LDAPControl ***clientctrls ); + void addControlOp( LDAPControl ***pctrls, const TQString &oid, + const TQByteArray &value, bool critical ); + void addModOp( LDAPMod ***pmods, int mod_type, + const TQString &attr, const TQByteArray &value ); + void LDAPEntry2UDSEntry( const TQString &dn, TDEIO::UDSEntry &entry, + const KABC::LDAPUrl &usrc, bool dir=false ); + int asyncSearch( KABC::LDAPUrl &usrc ); + + TQCString LDAPEntryAsLDIF( LDAPMessage *msg ); + void LDAPErr( const KURL &url, int err = LDAP_SUCCESS ); + void changeCheck( KABC::LDAPUrl &url ); + + void fillAuthInfo( TDEIO::AuthInfo &info ); +}; + +#endif diff --git a/tdeioslave/mac/CMakeLists.txt b/tdeioslave/mac/CMakeLists.txt index 6b1b92f6e..36c141a35 100644 --- a/tdeioslave/mac/CMakeLists.txt +++ b/tdeioslave/mac/CMakeLists.txt @@ -26,12 +26,12 @@ install( FILES mac.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) tde_install_icons( ) -##### kio_mac (module) ########################## +##### tdeio_mac (module) ########################## -set( target kio_mac ) +set( target tdeio_mac ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_mac.cpp + SOURCES tdeio_mac.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/mac/ChangeLog b/tdeioslave/mac/ChangeLog index 6c8f647ce..5de37eda2 100644 --- a/tdeioslave/mac/ChangeLog +++ b/tdeioslave/mac/ChangeLog @@ -18,7 +18,7 @@ - Converts some HFS+ file types and application labels into mimetypes - Added a SuSE Makefile - Hopefully managed to get the SuSE RPMs working - - When copying files kio-mac now reports the amount progressed so + - When copying files tdeio-mac now reports the amount progressed so you can see how much has been copied - Text files are now copies over in text mode by default diff --git a/tdeioslave/mac/Makefile.am b/tdeioslave/mac/Makefile.am index dfd79d822..42f73b507 100644 --- a/tdeioslave/mac/Makefile.am +++ b/tdeioslave/mac/Makefile.am @@ -1,17 +1,17 @@ -## Makfile.am for kio_mac +## Makfile.am for tdeio_mac INCLUDES= $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor ####### Files -kde_module_LTLIBRARIES = kio_mac.la +kde_module_LTLIBRARIES = tdeio_mac.la -kio_mac_la_SOURCES = kio_mac.cpp -kio_mac_la_LIBADD = -lkio -kio_mac_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_mac_la_SOURCES = tdeio_mac.cpp +tdeio_mac_la_LIBADD = -ltdeio +tdeio_mac_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_mac.h +noinst_HEADERS = tdeio_mac.h kdelnk_DATA = mac.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/mac/README b/tdeioslave/mac/README index bb907dd9c..7ac1b5a3d 100644 --- a/tdeioslave/mac/README +++ b/tdeioslave/mac/README @@ -7,7 +7,7 @@ From the hfsplus man page: 2^64 blocks, resulting in much more efficient storage of many small files on large disks." -This kio slave lets you read an HFS+ partition from konqueror +This tdeio slave lets you read an HFS+ partition from konqueror or any other KDE file dialogue. It uses hfsplus tools so you will need these installed for it to work. @@ -52,7 +52,7 @@ For some reason some directories in MacOS end in a funny tall f character. This seems to confuse hfstools. You can't easiily use the command line tools while you are browsing -using kio-mac in Konqueror. Konqueror continuously refreshes it's +using tdeio-mac in Konqueror. Konqueror continuously refreshes it's view which mean hpmount is being called every few seconds. Click on Konqueror's home button before using the tools yourself on the command line. diff --git a/tdeioslave/mac/TODO b/tdeioslave/mac/TODO index e94d88254..69fcb0d2e 100644 --- a/tdeioslave/mac/TODO +++ b/tdeioslave/mac/TODO @@ -1,7 +1,7 @@ FIXMEs: Amazingly, none that I can think of -grep TODO kio_mac.cpp +grep TODO tdeio_mac.cpp //TODO this means dev=foo must be the last argument in the query //TODO this error interrupts the user when typing ?dev=foo on each letter of foo //TODO are there any more characters to escape? diff --git a/tdeioslave/mac/kio_mac.cpp b/tdeioslave/mac/kio_mac.cpp deleted file mode 100644 index d26cc47e5..000000000 --- a/tdeioslave/mac/kio_mac.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/*************************************************************************** - kio_mac.cpp - ------------------- - copyright : (C) 2002 Jonathan Riddell - email : jr@jriddell.org - version : 1.0.1 - release date : 19 July 2002 - ***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#define PARTITION "/dev/hda11" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "kio_mac.moc" - -using namespace TDEIO; - -extern "C" { - int KDE_EXPORT kdemain(int, char **argv) { - TDEInstance instance("kio_mac"); - MacProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - return 0; - } -} - -MacProtocol::MacProtocol(const TQCString &pool, const TQCString &app) - : TQObject(), SlaveBase("mac", pool, app) { -/* logFile = new TQFile("/home/jr/logfile"); - logFile->open(IO_ReadWrite | IO_Append); - logStream = new TQTextStream(logFile); - *logStream << "Start Macprotocol()" << endl; - */ -} - -MacProtocol::~MacProtocol() { -/* *logStream << "destructor ~MacProtocol()" << endl; - logFile->close(); - delete logFile; - logFile = 0; - delete logStream; - logStream = 0; -*/ - delete myTDEProcess; - myTDEProcess = 0L; -} - -//get() called when a file is to be read -void MacProtocol::get(const KURL& url) { - TQString path = prepareHP(url); //mount and change to correct directory - return the filename - TQString query = url.query(); - TQString mode("-"); - TQString mime; - processedBytes = 0; - - //Find out the size and if it's a text file - UDSEntry entry = doStat(url); - UDSEntry::Iterator it; - for(it = entry.begin(); it != entry.end(); ++it) { - if ((*it).m_uds == TDEIO::UDS_MIME_TYPE) { - mime = (*it).m_str; - } - if ((*it).m_uds == TDEIO::UDS_SIZE) { - totalSize((*it).m_long); - } - } - - //find out if a mode has been specified in the query e.g. ?mode=t - //or if it's a text file then set the mode to text - int modepos = query.find("mode="); - int textpos = mime.find("text"); - if (modepos != -1) { - mode += query.mid(modepos + 5, 1); - if (mode != "-r" && mode != "-b" && mode != "-m" && mode != "-t" && mode != "-a") { - error(ERR_SLAVE_DEFINED, i18n("Unknown mode")); - } - } else if (textpos != -1) { - mode += "t"; - } else { - mode += "r"; - } - - //now we can read the file - myTDEProcess = new TDEProcess(); - - *myTDEProcess << "hpcopy" << mode << path << "-"; - - //data is now sent directly from the slot - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotSetDataStdOutput(TDEProcess *, char *, int))); - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - if (!myTDEProcess->normalExit() || !(myTDEProcess->exitStatus() == 0)) { - error(ERR_SLAVE_DEFINED, - i18n("There was an error with hpcopy - please ensure it is installed")); - return; - } - - //clean up - delete myTDEProcess; myTDEProcess = 0; - //finish - data(TQByteArray()); - finished(); -} - -//listDir() called when the user is looking at a directory -void MacProtocol::listDir(const KURL& url) { - TQString filename = prepareHP(url); - - if (filename.isNull()) { - error(ERR_CANNOT_LAUNCH_PROCESS, i18n("No filename was found")); - } else { - myTDEProcess = new TDEProcess(); - *myTDEProcess << "hpls" << "-la" << filename; - - standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { - error(ERR_SLAVE_DEFINED, - i18n("There was an error with hpls - please ensure it is installed")); - } - - //clean up - delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - UDSEntry entry; - if (!standardOutputStream.isEmpty()) { - TQTextStream in(&standardOutputStream, IO_ReadOnly); - TQString line = in.readLine(); //throw away top file which shows current directory - line = in.readLine(); - - while (line != NULL) { - //1.0.4 puts this funny line in sometimes, we don't want it - if (line.contains("Thread ") == 0) { - entry = makeUDS(line); - listEntry(entry, false); - } - line = in.readLine(); - } - }//if standardOutputStream != null - - listEntry(entry, true); - finished(); - - }//if filename == null -} - -//stat() called to see if it's a file or directory, called before listDir() or get() -void MacProtocol::stat(const KURL& url) { - statEntry(doStat(url)); - finished(); -} - -//doStat(), does all the work that stat() needs -//it's been separated out so it can be called from get() which -//also need information -TQValueList MacProtocol::doStat(const KURL& url) { - TQString filename = prepareHP(url); - - if (filename.isNull()) { - error(ERR_SLAVE_DEFINED, i18n("No filename was found in the URL")); - } else if (! filename.isEmpty()) { - myTDEProcess = new KShellProcess(); - - *myTDEProcess << "hpls" << "-ld" << filename; - - standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { - error(ERR_SLAVE_DEFINED, - i18n("hpls did not exit normally - please ensure you have installed the hfsplus tools")); - } - - //clean up - delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - if (standardOutputStream.isEmpty()) { - filename.replace("\\ ", " "); //get rid of escapes - filename.replace("\\&", "&"); //mm, slashes... - filename.replace("\\!", "!"); - filename.replace("\\(", "("); - filename.replace("\\)", ")"); - error(ERR_DOES_NOT_EXIST, filename); - } else { - //remove trailing \n - TQString line = standardOutputStream.left(standardOutputStream.length()-1); - UDSEntry entry = makeUDS(line); - return entry; - } - } else { //filename is empty means we're looking at root dir - //we don't have a listing for the root directory so here's a dummy one - UDSEntry entry = makeUDS("d 0 item Jan 01 2000 /"); - return entry; - }//if filename == null - - return TQValueList(); -} - -//prepareHP() called from get() listDir() and stat() -//(re)mounts the partition and changes to the appropriate directory -TQString MacProtocol::prepareHP(const KURL& url) { - TQString path = url.path(-1); - if (path.left(1) == "/") { - path = path.mid(1); // strip leading slash - } - - //find out if a device has been specified in the query e.g. ?dev=/dev/fd0 - //or in the config file (query device entries are saved to config file) - TQString device; - TDEConfig* config = new TDEConfig("macrc"); - - TQString query = url.query(); - int modepos = query.find("dev="); - if (modepos == -1) { - //no device specified, read from config or go with #define PARTITION - device = config->readEntry("device",PARTITION); - } else { - //TODO this means dev=foo must be the last argument in the query - device = query.mid(modepos + 4); - config->writeEntry("device",device); - } - delete config; config = 0; - - //first we run just hpmount and check the output to see if it's version 1.0.2 or 1.0.4 - myTDEProcess = new TDEProcess(); - *myTDEProcess << "hpmount"; - standardOutputStream = TQString::null; - connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - bool version102 = true; - - if (standardOutputStream.contains("options") != 0) { - version102 = false; - } - - delete myTDEProcess; myTDEProcess = 0; - disconnect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - - //now mount the drive - myTDEProcess = new TDEProcess(); - if (version102) { - *myTDEProcess << "hpmount" << device; - } else { - *myTDEProcess << "hpmount" << "-r" << device; - } - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { - //TODO this error interrupts the user when typing ?dev=foo on each letter of foo - error(ERR_SLAVE_DEFINED, - i18n("hpmount did not exit normally - please ensure that hfsplus utils are installed,\n" - "that you have permission to read the partition (ls -l /dev/hdaX)\n" - "and that you have specified the correct partition.\n" - "You can specify partitions by adding ?dev=/dev/hda2 to the URL.")); - return NULL; - } - - //clean up - delete myTDEProcess; myTDEProcess = 0; - - //escape any funny characters - //TODO are there any more characters to escape? - path.replace(" ", "\\ "); - path.replace("&", "\\&"); - path.replace("!", "\\!"); - path.replace("(", "\\("); - path.replace(")", "\\)"); - - //then change to the right directory - int s; TQString dir; - s = path.find('/'); - while (s != -1) { - dir = path.left(s); - path = path.mid(s+1); - - myTDEProcess = new TDEProcess(); - *myTDEProcess << "hpcd" << dir; - - myTDEProcess->start(TDEProcess::Block, TDEProcess::All); - - if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { - error(ERR_SLAVE_DEFINED, - i18n("hpcd did not exit normally - please ensure it is installed")); - return NULL; - } - - //clean up - delete myTDEProcess; myTDEProcess = 0; - - s = path.find('/'); - } - - return path; -} - -//makeUDS() takes a line of output from hpls -l and converts it into -// one of these UDSEntrys to return -//called from listDir() and stat() -TQValueList MacProtocol::makeUDS(const TQString& _line) { - TQString line(_line); - UDSEntry entry; - - //is it a file or a directory - TQRegExp dirRE("^d. +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)"); - TQRegExp fileRE("^([f|F]). +(....)/(....) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)"); - if (dirRE.exactMatch(line)) { - UDSAtom atom; - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = dirRE.cap(6); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; - atom.m_long = makeTime(dirRE.cap(4), dirRE.cap(3), dirRE.cap(5)); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = 0755; - entry.append(atom); - - } else if (fileRE.exactMatch(line)) { - UDSAtom atom; - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = fileRE.cap(9); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_SIZE; - TQString theSize(fileRE.cap(4)); //TODO: this is data size, what about resource size? - atom.m_long = theSize.toLong(); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; - atom.m_long = makeTime(fileRE.cap(7), fileRE.cap(6), fileRE.cap(8)); - entry.append(atom); - - atom.m_uds = TDEIO::UDS_ACCESS; - if (TQString(fileRE.cap(1)) == TQString("F")) { //if locked then read only - atom.m_long = 0444; - } else { - atom.m_long = 0644; - } - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MIME_TYPE; - TQString mimetype = getMimetype(fileRE.cap(2),fileRE.cap(3)); - atom.m_str = mimetype.local8Bit(); - entry.append(atom); - - // Is it a file or a link/alias, just make aliases link to themselves - if (TQString(fileRE.cap(2)) == TQString("adrp") || - TQString(fileRE.cap(2)) == TQString("fdrp")) { - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_LINK_DEST; - atom.m_str = fileRE.cap(9); //I have a file called "Mozilla alias" the name - // of which displays funny because of this. - // No idea why. Same for other tdeioslaves. A font thing? - entry.append(atom); - } else { - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - } - } else { - error(ERR_INTERNAL, i18n("hpls output was not matched")); - } //if match dirRE or fileRE - - return entry; -} - -//slotGetStdOutput() grabs output from the hp commands -// and adds it to the buffer -void MacProtocol::slotGetStdOutput(TDEProcess*, char *s, int len) { - standardOutputStream += TQString::fromLocal8Bit(s, len); -} - -//slotSetDataStdOutput() is used during hpcopy to give -//standard output to KDE -void MacProtocol::slotSetDataStdOutput(TDEProcess*, char *s, int len) { - processedBytes += len; - processedSize(processedBytes); - TQByteArray array; - array.setRawData(s, len); - data(array); - array.resetRawData(s, len); -} - -//makeTime() takes in the date output from hpls -l -//and returns as good a timestamp as we're going to get -int MacProtocol::makeTime(TQString mday, TQString mon, TQString third) { - int year; int month; int day; - int hour; int minute; - - //find the month - if (mon == "Jan") { month = 1; } - else if (mon == "Feb") { month = 2; } - else if (mon == "Mar") { month = 3; } - else if (mon == "Apr") { month = 4; } - else if (mon == "May") { month = 5; } - else if (mon == "Jun") { month = 6; } - else if (mon == "Jul") { month = 7; } - else if (mon == "Aug") { month = 8; } - else if (mon == "Sep") { month = 9; } - else if (mon == "Oct") { month = 10; } - else if (mon == "Nov") { month = 11; } - else if (mon == "Dec") { month = 12; } - else { - error(ERR_INTERNAL, i18n("Month output from hpls -l not matched")); - month = 13; - } - - //if the file is recent (last 12 months) hpls gives us the time, - // otherwise it only prints the year - TQRegExp hourMin("(..):(..)"); - if (hourMin.exactMatch(third)) { - TQDate currentDate(TQDate::currentDate()); - - if (month > currentDate.month()) { - year = currentDate.year() - 1; - } else { - year = currentDate.year(); - } - TQString h(hourMin.cap(1)); - TQString m(hourMin.cap(2)); - hour = h.toInt(); - minute = m.toInt(); - } else { - year = third.toInt(); - hour = 0; - minute = 0; - }// if hour:min or year - - day = mday.toInt(); - - //check it's valid - if ( (!TQDate::isValid(year, month, day)) || (!TQTime::isValid(hour, minute, 0) ) ) { - error(ERR_INTERNAL, i18n("Could not parse a valid date from hpls")); - } - - //put it together and work it out - TQDate fileDate(year, month, day); - TQTime fileTime(hour, minute); - TQDateTime fileDateTime(fileDate, fileTime); - - return fileDateTime.toTime_t(); -} - -TQString MacProtocol::getMimetype(TQString type, TQString app) { - if (type == TQString("TEXT") && app == TQString("ttxt")) { - return TQString("text/plain"); - } else if (type == TQString("TEXT") && app == TQString("udog")) { - return TQString("text/html"); - } else if (type == TQString("svgs")) { - return TQString("text/xml"); - } else if (type == TQString("ZIP ")) { - return TQString("application/zip"); - } else if (type == TQString("pZip")) { - return TQString("application/zip"); - } else if (type == TQString("APPL")) { - return TQString("application/x-executable"); - } else if (type == TQString("MooV")) { - return TQString("video/quicktime"); - } else if (type == TQString("TEXT") && app == TQString("MSWD")) { - return TQString("application/vnd.ms-word"); - } else if (type == TQString("PDF ")) { - return TQString("application/pdf"); - } else if (app == TQString("CARO")) { - return TQString("application/pdf"); - } else if (type == TQString("SIT5")) { - return TQString("application/x-stuffit"); - } else if (type == TQString("SITD")) { - return TQString("application/x-stuffit"); - } else if (type == TQString("SIT!")) { - return TQString("application/x-stuffit"); - } else if (app == TQString("SIT!")) { - return TQString("application/x-stuffit"); - } else if (type == TQString("RTFf")) { - return TQString("text/rtf"); - } else if (type == TQString("GIFf")) { - return TQString("image/gif"); - } else if (type == TQString("JPEG")) { - return TQString("image/jpeg"); - } else if (type == TQString("PNGf")) { - return TQString("image/png"); - } else if (type == TQString("XBMm")) { - return TQString("image/x-xbm"); - } else if (type == TQString("EPSF")) { - return TQString("image/x-epsf"); - } else if (type == TQString("TIFF")) { - return TQString("image/tiff"); - } else if (type == TQString("PICT")) { - return TQString("image/pict"); - } else if (type == TQString("TPIC")) { - return TQString("image/x-targa"); - } else if (type == TQString("ULAW")) { - return TQString("audio/basic"); - } else if (type == TQString("AIFF")) { - return TQString("audio/x-aiff"); - } else if (type == TQString("WAVE")) { - return TQString("audio/x-wav"); - } else if (type == TQString("FFIL") && app == TQString("DMOV")) { - return TQString("application/x-font"); - } else if (type == TQString("XLS3")) { - return TQString("application/vnd.ms-excel"); - } else if (type == TQString("XLS4")) { - return TQString("application/vnd.ms-excel"); - } else if (type == TQString("XLS5")) { - return TQString("application/vnd.ms-excel"); - } else if (app == TQString("MSWD")) { - return TQString("application/vnd.ms-word"); - } else if (type == TQString("TEXT")) { - return TQString("text/plain"); - } else if (app == TQString("ttxt")) { - return TQString("text/plain"); - } - return TQString("application/octet-stream"); -} - - diff --git a/tdeioslave/mac/kio_mac.h b/tdeioslave/mac/kio_mac.h deleted file mode 100644 index e497e9918..000000000 --- a/tdeioslave/mac/kio_mac.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - mac.cpp - ------------------- - copyright : (C) 2002 Jonathan Riddell - email : jr@jriddell.org - version : 1.0 - release date : 10 Feburary 2002 - ***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include -#include -#include -#include - -#include -#include -#include -#include - -class MacProtocol : public TQObject, public TDEIO::SlaveBase -{ - Q_OBJECT -public: - MacProtocol(const TQCString &pool, const TQCString &app); - ~MacProtocol(); - virtual void get(const KURL& url ); - virtual void listDir(const KURL& url); - virtual void stat(const KURL& url); -protected slots: - void slotGetStdOutput(TDEProcess*, char*, int); - void slotSetDataStdOutput(TDEProcess*, char *s, int len); -protected: - TQString prepareHP(const KURL& _url); - TQValueList makeUDS(const TQString& _line); - int makeTime(TQString mday, TQString mon, TQString third); - TQString getMimetype(TQString type, TQString app); - TQValueList doStat(const KURL& url); - - TDEIO::filesize_t processedBytes; - TQString standardOutputStream; - TDEProcess* myTDEProcess; - - //for debugging - //TQFile* logFile; - //TQTextStream* logStream; -}; diff --git a/tdeioslave/mac/mac.protocol b/tdeioslave/mac/mac.protocol index 9e94132bb..1a9044158 100644 --- a/tdeioslave/mac/mac.protocol +++ b/tdeioslave/mac/mac.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_mac +exec=tdeio_mac protocol=mac input=none output=filesystem diff --git a/tdeioslave/mac/tdeio_mac.cpp b/tdeioslave/mac/tdeio_mac.cpp new file mode 100644 index 000000000..707d995ee --- /dev/null +++ b/tdeioslave/mac/tdeio_mac.cpp @@ -0,0 +1,561 @@ +/*************************************************************************** + tdeio_mac.cpp + ------------------- + copyright : (C) 2002 Jonathan Riddell + email : jr@jriddell.org + version : 1.0.1 + release date : 19 July 2002 + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#define PARTITION "/dev/hda11" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tdeio_mac.moc" + +using namespace TDEIO; + +extern "C" { + int KDE_EXPORT kdemain(int, char **argv) { + TDEInstance instance("tdeio_mac"); + MacProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; + } +} + +MacProtocol::MacProtocol(const TQCString &pool, const TQCString &app) + : TQObject(), SlaveBase("mac", pool, app) { +/* logFile = new TQFile("/home/jr/logfile"); + logFile->open(IO_ReadWrite | IO_Append); + logStream = new TQTextStream(logFile); + *logStream << "Start Macprotocol()" << endl; + */ +} + +MacProtocol::~MacProtocol() { +/* *logStream << "destructor ~MacProtocol()" << endl; + logFile->close(); + delete logFile; + logFile = 0; + delete logStream; + logStream = 0; +*/ + delete myTDEProcess; + myTDEProcess = 0L; +} + +//get() called when a file is to be read +void MacProtocol::get(const KURL& url) { + TQString path = prepareHP(url); //mount and change to correct directory - return the filename + TQString query = url.query(); + TQString mode("-"); + TQString mime; + processedBytes = 0; + + //Find out the size and if it's a text file + UDSEntry entry = doStat(url); + UDSEntry::Iterator it; + for(it = entry.begin(); it != entry.end(); ++it) { + if ((*it).m_uds == TDEIO::UDS_MIME_TYPE) { + mime = (*it).m_str; + } + if ((*it).m_uds == TDEIO::UDS_SIZE) { + totalSize((*it).m_long); + } + } + + //find out if a mode has been specified in the query e.g. ?mode=t + //or if it's a text file then set the mode to text + int modepos = query.find("mode="); + int textpos = mime.find("text"); + if (modepos != -1) { + mode += query.mid(modepos + 5, 1); + if (mode != "-r" && mode != "-b" && mode != "-m" && mode != "-t" && mode != "-a") { + error(ERR_SLAVE_DEFINED, i18n("Unknown mode")); + } + } else if (textpos != -1) { + mode += "t"; + } else { + mode += "r"; + } + + //now we can read the file + myTDEProcess = new TDEProcess(); + + *myTDEProcess << "hpcopy" << mode << path << "-"; + + //data is now sent directly from the slot + connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotSetDataStdOutput(TDEProcess *, char *, int))); + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + if (!myTDEProcess->normalExit() || !(myTDEProcess->exitStatus() == 0)) { + error(ERR_SLAVE_DEFINED, + i18n("There was an error with hpcopy - please ensure it is installed")); + return; + } + + //clean up + delete myTDEProcess; myTDEProcess = 0; + //finish + data(TQByteArray()); + finished(); +} + +//listDir() called when the user is looking at a directory +void MacProtocol::listDir(const KURL& url) { + TQString filename = prepareHP(url); + + if (filename.isNull()) { + error(ERR_CANNOT_LAUNCH_PROCESS, i18n("No filename was found")); + } else { + myTDEProcess = new TDEProcess(); + *myTDEProcess << "hpls" << "-la" << filename; + + standardOutputStream = TQString::null; + connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { + error(ERR_SLAVE_DEFINED, + i18n("There was an error with hpls - please ensure it is installed")); + } + + //clean up + delete myTDEProcess; myTDEProcess = 0; + disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + UDSEntry entry; + if (!standardOutputStream.isEmpty()) { + TQTextStream in(&standardOutputStream, IO_ReadOnly); + TQString line = in.readLine(); //throw away top file which shows current directory + line = in.readLine(); + + while (line != NULL) { + //1.0.4 puts this funny line in sometimes, we don't want it + if (line.contains("Thread ") == 0) { + entry = makeUDS(line); + listEntry(entry, false); + } + line = in.readLine(); + } + }//if standardOutputStream != null + + listEntry(entry, true); + finished(); + + }//if filename == null +} + +//stat() called to see if it's a file or directory, called before listDir() or get() +void MacProtocol::stat(const KURL& url) { + statEntry(doStat(url)); + finished(); +} + +//doStat(), does all the work that stat() needs +//it's been separated out so it can be called from get() which +//also need information +TQValueList MacProtocol::doStat(const KURL& url) { + TQString filename = prepareHP(url); + + if (filename.isNull()) { + error(ERR_SLAVE_DEFINED, i18n("No filename was found in the URL")); + } else if (! filename.isEmpty()) { + myTDEProcess = new KShellProcess(); + + *myTDEProcess << "hpls" << "-ld" << filename; + + standardOutputStream = TQString::null; + connect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { + error(ERR_SLAVE_DEFINED, + i18n("hpls did not exit normally - please ensure you have installed the hfsplus tools")); + } + + //clean up + delete myTDEProcess; myTDEProcess = 0; + disconnect(myTDEProcess, TQT_SIGNAL(receivedStdout(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + if (standardOutputStream.isEmpty()) { + filename.replace("\\ ", " "); //get rid of escapes + filename.replace("\\&", "&"); //mm, slashes... + filename.replace("\\!", "!"); + filename.replace("\\(", "("); + filename.replace("\\)", ")"); + error(ERR_DOES_NOT_EXIST, filename); + } else { + //remove trailing \n + TQString line = standardOutputStream.left(standardOutputStream.length()-1); + UDSEntry entry = makeUDS(line); + return entry; + } + } else { //filename is empty means we're looking at root dir + //we don't have a listing for the root directory so here's a dummy one + UDSEntry entry = makeUDS("d 0 item Jan 01 2000 /"); + return entry; + }//if filename == null + + return TQValueList(); +} + +//prepareHP() called from get() listDir() and stat() +//(re)mounts the partition and changes to the appropriate directory +TQString MacProtocol::prepareHP(const KURL& url) { + TQString path = url.path(-1); + if (path.left(1) == "/") { + path = path.mid(1); // strip leading slash + } + + //find out if a device has been specified in the query e.g. ?dev=/dev/fd0 + //or in the config file (query device entries are saved to config file) + TQString device; + TDEConfig* config = new TDEConfig("macrc"); + + TQString query = url.query(); + int modepos = query.find("dev="); + if (modepos == -1) { + //no device specified, read from config or go with #define PARTITION + device = config->readEntry("device",PARTITION); + } else { + //TODO this means dev=foo must be the last argument in the query + device = query.mid(modepos + 4); + config->writeEntry("device",device); + } + delete config; config = 0; + + //first we run just hpmount and check the output to see if it's version 1.0.2 or 1.0.4 + myTDEProcess = new TDEProcess(); + *myTDEProcess << "hpmount"; + standardOutputStream = TQString::null; + connect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + bool version102 = true; + + if (standardOutputStream.contains("options") != 0) { + version102 = false; + } + + delete myTDEProcess; myTDEProcess = 0; + disconnect(myTDEProcess, TQT_SIGNAL(receivedStderr(TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + + //now mount the drive + myTDEProcess = new TDEProcess(); + if (version102) { + *myTDEProcess << "hpmount" << device; + } else { + *myTDEProcess << "hpmount" << "-r" << device; + } + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { + //TODO this error interrupts the user when typing ?dev=foo on each letter of foo + error(ERR_SLAVE_DEFINED, + i18n("hpmount did not exit normally - please ensure that hfsplus utils are installed,\n" + "that you have permission to read the partition (ls -l /dev/hdaX)\n" + "and that you have specified the correct partition.\n" + "You can specify partitions by adding ?dev=/dev/hda2 to the URL.")); + return NULL; + } + + //clean up + delete myTDEProcess; myTDEProcess = 0; + + //escape any funny characters + //TODO are there any more characters to escape? + path.replace(" ", "\\ "); + path.replace("&", "\\&"); + path.replace("!", "\\!"); + path.replace("(", "\\("); + path.replace(")", "\\)"); + + //then change to the right directory + int s; TQString dir; + s = path.find('/'); + while (s != -1) { + dir = path.left(s); + path = path.mid(s+1); + + myTDEProcess = new TDEProcess(); + *myTDEProcess << "hpcd" << dir; + + myTDEProcess->start(TDEProcess::Block, TDEProcess::All); + + if ((!myTDEProcess->normalExit()) || (!myTDEProcess->exitStatus() == 0)) { + error(ERR_SLAVE_DEFINED, + i18n("hpcd did not exit normally - please ensure it is installed")); + return NULL; + } + + //clean up + delete myTDEProcess; myTDEProcess = 0; + + s = path.find('/'); + } + + return path; +} + +//makeUDS() takes a line of output from hpls -l and converts it into +// one of these UDSEntrys to return +//called from listDir() and stat() +TQValueList MacProtocol::makeUDS(const TQString& _line) { + TQString line(_line); + UDSEntry entry; + + //is it a file or a directory + TQRegExp dirRE("^d. +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)"); + TQRegExp fileRE("^([f|F]). +(....)/(....) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)"); + if (dirRE.exactMatch(line)) { + UDSAtom atom; + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = dirRE.cap(6); + entry.append(atom); + + atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; + atom.m_long = makeTime(dirRE.cap(4), dirRE.cap(3), dirRE.cap(5)); + entry.append(atom); + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append(atom); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = 0755; + entry.append(atom); + + } else if (fileRE.exactMatch(line)) { + UDSAtom atom; + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = fileRE.cap(9); + entry.append(atom); + + atom.m_uds = TDEIO::UDS_SIZE; + TQString theSize(fileRE.cap(4)); //TODO: this is data size, what about resource size? + atom.m_long = theSize.toLong(); + entry.append(atom); + + atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; + atom.m_long = makeTime(fileRE.cap(7), fileRE.cap(6), fileRE.cap(8)); + entry.append(atom); + + atom.m_uds = TDEIO::UDS_ACCESS; + if (TQString(fileRE.cap(1)) == TQString("F")) { //if locked then read only + atom.m_long = 0444; + } else { + atom.m_long = 0644; + } + entry.append(atom); + + atom.m_uds = TDEIO::UDS_MIME_TYPE; + TQString mimetype = getMimetype(fileRE.cap(2),fileRE.cap(3)); + atom.m_str = mimetype.local8Bit(); + entry.append(atom); + + // Is it a file or a link/alias, just make aliases link to themselves + if (TQString(fileRE.cap(2)) == TQString("adrp") || + TQString(fileRE.cap(2)) == TQString("fdrp")) { + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + + atom.m_uds = TDEIO::UDS_LINK_DEST; + atom.m_str = fileRE.cap(9); //I have a file called "Mozilla alias" the name + // of which displays funny because of this. + // No idea why. Same for other tdeioslaves. A font thing? + entry.append(atom); + } else { + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + } + } else { + error(ERR_INTERNAL, i18n("hpls output was not matched")); + } //if match dirRE or fileRE + + return entry; +} + +//slotGetStdOutput() grabs output from the hp commands +// and adds it to the buffer +void MacProtocol::slotGetStdOutput(TDEProcess*, char *s, int len) { + standardOutputStream += TQString::fromLocal8Bit(s, len); +} + +//slotSetDataStdOutput() is used during hpcopy to give +//standard output to KDE +void MacProtocol::slotSetDataStdOutput(TDEProcess*, char *s, int len) { + processedBytes += len; + processedSize(processedBytes); + TQByteArray array; + array.setRawData(s, len); + data(array); + array.resetRawData(s, len); +} + +//makeTime() takes in the date output from hpls -l +//and returns as good a timestamp as we're going to get +int MacProtocol::makeTime(TQString mday, TQString mon, TQString third) { + int year; int month; int day; + int hour; int minute; + + //find the month + if (mon == "Jan") { month = 1; } + else if (mon == "Feb") { month = 2; } + else if (mon == "Mar") { month = 3; } + else if (mon == "Apr") { month = 4; } + else if (mon == "May") { month = 5; } + else if (mon == "Jun") { month = 6; } + else if (mon == "Jul") { month = 7; } + else if (mon == "Aug") { month = 8; } + else if (mon == "Sep") { month = 9; } + else if (mon == "Oct") { month = 10; } + else if (mon == "Nov") { month = 11; } + else if (mon == "Dec") { month = 12; } + else { + error(ERR_INTERNAL, i18n("Month output from hpls -l not matched")); + month = 13; + } + + //if the file is recent (last 12 months) hpls gives us the time, + // otherwise it only prints the year + TQRegExp hourMin("(..):(..)"); + if (hourMin.exactMatch(third)) { + TQDate currentDate(TQDate::currentDate()); + + if (month > currentDate.month()) { + year = currentDate.year() - 1; + } else { + year = currentDate.year(); + } + TQString h(hourMin.cap(1)); + TQString m(hourMin.cap(2)); + hour = h.toInt(); + minute = m.toInt(); + } else { + year = third.toInt(); + hour = 0; + minute = 0; + }// if hour:min or year + + day = mday.toInt(); + + //check it's valid + if ( (!TQDate::isValid(year, month, day)) || (!TQTime::isValid(hour, minute, 0) ) ) { + error(ERR_INTERNAL, i18n("Could not parse a valid date from hpls")); + } + + //put it together and work it out + TQDate fileDate(year, month, day); + TQTime fileTime(hour, minute); + TQDateTime fileDateTime(fileDate, fileTime); + + return fileDateTime.toTime_t(); +} + +TQString MacProtocol::getMimetype(TQString type, TQString app) { + if (type == TQString("TEXT") && app == TQString("ttxt")) { + return TQString("text/plain"); + } else if (type == TQString("TEXT") && app == TQString("udog")) { + return TQString("text/html"); + } else if (type == TQString("svgs")) { + return TQString("text/xml"); + } else if (type == TQString("ZIP ")) { + return TQString("application/zip"); + } else if (type == TQString("pZip")) { + return TQString("application/zip"); + } else if (type == TQString("APPL")) { + return TQString("application/x-executable"); + } else if (type == TQString("MooV")) { + return TQString("video/quicktime"); + } else if (type == TQString("TEXT") && app == TQString("MSWD")) { + return TQString("application/vnd.ms-word"); + } else if (type == TQString("PDF ")) { + return TQString("application/pdf"); + } else if (app == TQString("CARO")) { + return TQString("application/pdf"); + } else if (type == TQString("SIT5")) { + return TQString("application/x-stuffit"); + } else if (type == TQString("SITD")) { + return TQString("application/x-stuffit"); + } else if (type == TQString("SIT!")) { + return TQString("application/x-stuffit"); + } else if (app == TQString("SIT!")) { + return TQString("application/x-stuffit"); + } else if (type == TQString("RTFf")) { + return TQString("text/rtf"); + } else if (type == TQString("GIFf")) { + return TQString("image/gif"); + } else if (type == TQString("JPEG")) { + return TQString("image/jpeg"); + } else if (type == TQString("PNGf")) { + return TQString("image/png"); + } else if (type == TQString("XBMm")) { + return TQString("image/x-xbm"); + } else if (type == TQString("EPSF")) { + return TQString("image/x-epsf"); + } else if (type == TQString("TIFF")) { + return TQString("image/tiff"); + } else if (type == TQString("PICT")) { + return TQString("image/pict"); + } else if (type == TQString("TPIC")) { + return TQString("image/x-targa"); + } else if (type == TQString("ULAW")) { + return TQString("audio/basic"); + } else if (type == TQString("AIFF")) { + return TQString("audio/x-aiff"); + } else if (type == TQString("WAVE")) { + return TQString("audio/x-wav"); + } else if (type == TQString("FFIL") && app == TQString("DMOV")) { + return TQString("application/x-font"); + } else if (type == TQString("XLS3")) { + return TQString("application/vnd.ms-excel"); + } else if (type == TQString("XLS4")) { + return TQString("application/vnd.ms-excel"); + } else if (type == TQString("XLS5")) { + return TQString("application/vnd.ms-excel"); + } else if (app == TQString("MSWD")) { + return TQString("application/vnd.ms-word"); + } else if (type == TQString("TEXT")) { + return TQString("text/plain"); + } else if (app == TQString("ttxt")) { + return TQString("text/plain"); + } + return TQString("application/octet-stream"); +} + + diff --git a/tdeioslave/mac/tdeio_mac.h b/tdeioslave/mac/tdeio_mac.h new file mode 100644 index 000000000..e497e9918 --- /dev/null +++ b/tdeioslave/mac/tdeio_mac.h @@ -0,0 +1,55 @@ +/*************************************************************************** + mac.cpp + ------------------- + copyright : (C) 2002 Jonathan Riddell + email : jr@jriddell.org + version : 1.0 + release date : 10 Feburary 2002 + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +class MacProtocol : public TQObject, public TDEIO::SlaveBase +{ + Q_OBJECT +public: + MacProtocol(const TQCString &pool, const TQCString &app); + ~MacProtocol(); + virtual void get(const KURL& url ); + virtual void listDir(const KURL& url); + virtual void stat(const KURL& url); +protected slots: + void slotGetStdOutput(TDEProcess*, char*, int); + void slotSetDataStdOutput(TDEProcess*, char *s, int len); +protected: + TQString prepareHP(const KURL& _url); + TQValueList makeUDS(const TQString& _line); + int makeTime(TQString mday, TQString mon, TQString third); + TQString getMimetype(TQString type, TQString app); + TQValueList doStat(const KURL& url); + + TDEIO::filesize_t processedBytes; + TQString standardOutputStream; + TDEProcess* myTDEProcess; + + //for debugging + //TQFile* logFile; + //TQTextStream* logStream; +}; diff --git a/tdeioslave/man/CMakeLists.txt b/tdeioslave/man/CMakeLists.txt index fca109df0..ad3ed012b 100644 --- a/tdeioslave/man/CMakeLists.txt +++ b/tdeioslave/man/CMakeLists.txt @@ -9,7 +9,7 @@ # ################################################# -# FIXME not built: man2html, kio_man_test +# FIXME not built: man2html, tdeio_man_test ##### system checks ############################# @@ -35,15 +35,15 @@ link_directories( ##### other data ################################ install( FILES man.protocol kmanpart.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) -install( FILES kio_man.css DESTINATION ${DATA_INSTALL_DIR}/tdeio_man ) +install( FILES tdeio_man.css DESTINATION ${DATA_INSTALL_DIR}/tdeio_man ) -##### kio_man (module) ########################## +##### tdeio_man (module) ########################## -set( target kio_man ) +set( target tdeio_man ) tde_add_kpart( ${target} AUTOMOC - SOURCES man2html.cpp kio_man.cpp + SOURCES man2html.cpp tdeio_man.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/man/Makefile.am b/tdeioslave/man/Makefile.am index d43edb74d..7b2554ba0 100644 --- a/tdeioslave/man/Makefile.am +++ b/tdeioslave/man/Makefile.am @@ -3,22 +3,22 @@ INCLUDES= $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -EXTRA_PROGRAMS = kio_man_test man2html +EXTRA_PROGRAMS = tdeio_man_test man2html ####### just for testing (j.habenicht@europemail.com, 15.02.2001) -kio_man_test_SOURCES = kio_man_test.cpp -kio_man_test_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -kio_man_test_LDADD = man2html.lo kio_man.lo $(LIB_KIO) $(LIB_TDEUI) $(LIB_TDECORE) $(LIB_QT) +tdeio_man_test_SOURCES = tdeio_man_test.cpp +tdeio_man_test_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +tdeio_man_test_LDADD = man2html.lo tdeio_man.lo $(LIB_KIO) $(LIB_TDEUI) $(LIB_TDECORE) $(LIB_QT) ####### Files -kde_module_LTLIBRARIES = kio_man.la libkmanpart.la +kde_module_LTLIBRARIES = tdeio_man.la libkmanpart.la -kio_man_la_SOURCES = man2html.cpp kio_man.cpp -kio_man_la_LIBADD = $(LIB_KSYCOCA) -kio_man_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_man.h +tdeio_man_la_SOURCES = man2html.cpp tdeio_man.cpp +tdeio_man_la_LIBADD = $(LIB_KSYCOCA) +tdeio_man_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +noinst_HEADERS = tdeio_man.h ### TODO Why is man2htmk.h distributed? libkmanpart_la_SOURCES = kmanpart.cpp @@ -28,9 +28,9 @@ libkmanpart_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) kdelnk_DATA = man.protocol kmanpart.desktop kdelnkdir = $(kde_servicesdir) -kio_man_data_DATA = kio_man.css -kio_man_datadir = $(kde_datadir)/tdeio_man -EXTRA_DIST=$(kio_man_data_DATA) +tdeio_man_data_DATA = tdeio_man.css +tdeio_man_datadir = $(kde_datadir)/tdeio_man +EXTRA_DIST=$(tdeio_man_data_DATA) METASOURCES = AUTO diff --git a/tdeioslave/man/kio_man.cpp b/tdeioslave/man/kio_man.cpp deleted file mode 100644 index d2ef8cb94..000000000 --- a/tdeioslave/man/kio_man.cpp +++ /dev/null @@ -1,1533 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (c) 2000 Matthias Hoelzer-Kluepfel - - 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "kio_man.h" -#include "kio_man.moc" -#include "man2html.h" -#include -#include -#include - -using namespace TDEIO; - -MANProtocol *MANProtocol::_self = 0; - -#define SGML2ROFF_DIRS "/usr/lib/sgml" - -/* - * Drop trailing ".section[.gz]" from name - */ -static -void stripExtension( TQString *name ) -{ - int pos = name->length(); - - if ( name->find(".gz", -3) != -1 ) - pos -= 3; - else if ( name->find(".z", -2, false) != -1 ) - pos -= 2; - else if ( name->find(".bz2", -4) != -1 ) - pos -= 4; - else if ( name->find(".bz", -3) != -1 ) - pos -= 3; - - if ( pos > 0 ) - pos = name->findRev('.', pos-1); - - if ( pos > 0 ) - name->truncate( pos ); -} - -static -bool parseUrl(const TQString& _url, TQString &title, TQString §ion) -{ - section = TQString::null; - - TQString url = _url; - if (url.at(0) == '/') { - if (KStandardDirs::exists(url)) { - title = url; - return true; - } else - { - // If the directory does not exist, then it is perhaps a normal man page - kdDebug(7107) << url << " does not exist" << endl; - } - } - - while (url.at(0) == '/') - url.remove(0,1); - - title = url; - - int pos = url.find('('); - if (pos < 0) - return true; - - title = title.left(pos); - - section = url.mid(pos+1); - section = section.left(section.length()-1); - - return true; -} - - -MANProtocol::MANProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : TQObject(), SlaveBase("man", pool_socket, app_socket) -{ - assert(!_self); - _self = this; - const TQString common_dir = TDEGlobal::dirs()->findResourceDir( "html", "en/common/kde-common.css" ); - const TQString strPath=TQString( "file:%1/en/common" ).arg( common_dir ); - m_htmlPath=strPath.local8Bit(); // ### TODO encode for HTML - m_cssPath=strPath.local8Bit(); // ### TODO encode for CSS - section_names << "1" << "2" << "3" << "3n" << "3p" << "4" << "5" << "6" << "7" - << "8" << "9" << "l" << "n"; - m_manCSSFile = locate( "data", "kio_man/tdeio_man.css" ); -} - -MANProtocol *MANProtocol::self() { return _self; } - -MANProtocol::~MANProtocol() -{ - _self = 0; -} - -void MANProtocol::parseWhatIs( TQMap &i, TQTextStream &t, const TQString &mark ) -{ - TQRegExp re( mark ); - TQString l; - while ( !t.atEnd() ) - { - l = t.readLine(); - int pos = re.search( l ); - if (pos != -1) - { - TQString names = l.left(pos); - TQString descr = l.mid(pos + re.matchedLength()); - while ((pos = names.find(",")) != -1) - { - i[names.left(pos++)] = descr; - while (names[pos] == ' ') - pos++; - names = names.mid(pos); - } - i[names] = descr; - } - } -} - -bool MANProtocol::addWhatIs(TQMap &i, const TQString &name, const TQString &mark) -{ - TQFile f(name); - if (!f.open(IO_ReadOnly)) - return false; - TQTextStream t(&f); - parseWhatIs( i, t, mark ); - return true; -} - -TQMap MANProtocol::buildIndexMap(const TQString §ion) -{ - TQMap i; - TQStringList man_dirs = manDirectories(); - // Supplementary places for whatis databases - man_dirs += m_mandbpath; - if (man_dirs.find("/var/cache/man")==man_dirs.end()) - man_dirs << "/var/cache/man"; - if (man_dirs.find("/var/catman")==man_dirs.end()) - man_dirs << "/var/catman"; - - TQStringList names; - names << "whatis.db" << "whatis"; - TQString mark = "\\s+\\(" + section + "[a-z]*\\)\\s+-\\s+"; - - for ( TQStringList::ConstIterator it_dir = man_dirs.begin(); - it_dir != man_dirs.end(); - ++it_dir ) - { - if ( TQFile::exists( *it_dir ) ) { - TQStringList::ConstIterator it_name; - for ( it_name = names.begin(); - it_name != names.end(); - it_name++ ) - { - if (addWhatIs(i, (*it_dir) + "/" + (*it_name), mark)) - break; - } - if ( it_name == names.end() ) { - TDEProcess proc; - proc << "whatis" << "-M" << (*it_dir) << "-w" << "*"; - myStdStream = TQString::null; - connect( &proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int ) ), - TQT_SLOT( slotGetStdOutput( TDEProcess *, char *, int ) ) ); - proc.start( TDEProcess::Block, TDEProcess::Stdout ); - TQTextStream t( &myStdStream, IO_ReadOnly ); - parseWhatIs( i, t, mark ); - } - } - } - return i; -} - -TQStringList MANProtocol::manDirectories() -{ - checkManPaths(); - // - // Build a list of man directories including translations - // - TQStringList man_dirs; - - for ( TQStringList::ConstIterator it_dir = m_manpath.begin(); - it_dir != m_manpath.end(); - it_dir++ ) - { - // Translated pages in "/" if the directory - // exists - TQStringList languages = TDEGlobal::locale()->languageList(); - - for (TQStringList::ConstIterator it_lang = languages.begin(); - it_lang != languages.end(); - it_lang++ ) - { - if ( !(*it_lang).isEmpty() && (*it_lang) != TQString("C") ) { - TQString dir = (*it_dir) + '/' + (*it_lang); - - struct stat sbuf; - - if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 - && S_ISDIR( sbuf.st_mode ) ) - { - const TQString p = TQDir(dir).canonicalPath(); - if (!man_dirs.contains(p)) man_dirs += p; - } - } - } - - // Untranslated pages in "" - const TQString p = TQDir(*it_dir).canonicalPath(); - if (!man_dirs.contains(p)) man_dirs += p; - } - return man_dirs; -} - -TQStringList MANProtocol::findPages(const TQString &_section, - const TQString &title, - bool full_path) -{ - TQString section = _section; - - TQStringList list; - - // kdDebug() << "findPages '" << section << "' '" << title << "'\n"; - if (title.at(0) == '/') { - list.append(title); - return list; - } - - const TQString star( "*" ); - - // - // Find man sections in this directory - // - TQStringList sect_list; - if ( section.isEmpty() ) - section = star; - - if ( section != star ) - { - // - // Section given as argument - // - sect_list += section; - while (section.at(section.length() - 1).isLetter()) { - section.truncate(section.length() - 1); - sect_list += section; - } - } else { - sect_list += section; - } - - TQStringList man_dirs = manDirectories(); - - // - // Find man pages in the sections listed above - // - for ( TQStringList::ConstIterator it_sect = sect_list.begin(); - it_sect != sect_list.end(); - it_sect++ ) - { - TQString it_real = (*it_sect).lower(); - // - // Find pages - // - for ( TQStringList::ConstIterator it_dir = man_dirs.begin(); - it_dir != man_dirs.end(); - it_dir++ ) - { - TQString man_dir = (*it_dir); - - // - // Sections = all sub directories "man*" and "sman*" - // - DIR *dp = ::opendir( TQFile::encodeName( man_dir ) ); - - if ( !dp ) - continue; - - struct dirent *ep; - - const TQString man = TQString("man"); - const TQString sman = TQString("sman"); - - while ( (ep = ::readdir( dp )) != 0L ) { - const TQString file = TQFile::decodeName( ep->d_name ); - TQString sect = TQString::null; - - if ( file.startsWith( man ) ) - sect = file.mid(3); - else if (file.startsWith(sman)) - sect = file.mid(4); - - if (sect.lower()==it_real) it_real = sect; - - // Only add sect if not already contained, avoid duplicates - if (!sect_list.contains(sect) && _section.isEmpty()) { - kdDebug() << "another section " << sect << endl; - sect_list += sect; - } - } - - ::closedir( dp ); - - if ( *it_sect != star ) { // in that case we only look around for sections - const TQString dir = man_dir + TQString("/man") + (it_real) + '/'; - const TQString sdir = man_dir + TQString("/sman") + (it_real) + '/'; - - findManPagesInSection(dir, title, full_path, list); - findManPagesInSection(sdir, title, full_path, list); - } - } - } - -// kdDebug(7107) << "finished " << list << " " << sect_list << endl; - - return list; -} - -void MANProtocol::findManPagesInSection(const TQString &dir, const TQString &title, bool full_path, TQStringList &list) -{ - kdDebug() << "findManPagesInSection " << dir << " " << title << endl; - bool title_given = !title.isEmpty(); - - DIR *dp = ::opendir( TQFile::encodeName( dir ) ); - - if ( !dp ) - return; - - struct dirent *ep; - - while ( (ep = ::readdir( dp )) != 0L ) { - if ( ep->d_name[0] != '.' ) { - - TQString name = TQFile::decodeName( ep->d_name ); - - // check title if we're looking for a specific page - if ( title_given ) { - if ( !name.startsWith( title ) ) { - continue; - } - else { - // beginning matches, do a more thorough check... - TQString tmp_name = name; - stripExtension( &tmp_name ); - if ( tmp_name != title ) - continue; - } - } - - if ( full_path ) - name.prepend( dir ); - - list += name ; - } - } - ::closedir( dp ); -} - -void MANProtocol::output(const char *insert) -{ - if (insert) - { - m_outputBuffer.writeBlock(insert,strlen(insert)); - } - if (!insert || m_outputBuffer.at() >= 2048) - { - m_outputBuffer.close(); - data(m_outputBuffer.buffer()); - m_outputBuffer.setBuffer(TQByteArray()); - m_outputBuffer.open(IO_WriteOnly); - } -} - -// called by man2html -char *read_man_page(const char *filename) -{ - return MANProtocol::self()->readManPage(filename); -} - -// called by man2html -void output_real(const char *insert) -{ - MANProtocol::self()->output(insert); -} - -static TQString text2html(const TQString& txt) -{ - TQString reply = txt; - - reply = reply.replace('&', "&"); - reply = reply.replace('<', "<"); - reply = reply.replace('>', ">"); - reply = reply.replace('"', "&dquot;"); - reply = reply.replace('\'', """); - return reply; -} - -void MANProtocol::get(const KURL& url ) -{ - kdDebug(7107) << "GET " << url.url() << endl; - - TQString title, section; - - if (!parseUrl(url.path(), title, section)) - { - showMainIndex(); - return; - } - - // see if an index was requested - if (url.query().isEmpty() && (title.isEmpty() || title == "/" || title == ".")) - { - if (section == "index" || section.isEmpty()) - showMainIndex(); - else - showIndex(section); - return; - } - - // tell the mimetype - mimeType("text/html"); - - const TQStringList foundPages=findPages(section, title); - bool pageFound=true; - if (foundPages.isEmpty()) - { - outputError(i18n("No man page matching to %1 found.

" - "Check that you have not mistyped the name of the page that you want.\n" - "Be careful that you must take care about upper case and lower case characters!
" - "If everything looks correct, then perhaps you need to set a better search path " - "for man pages, be it by the environment variable MANPATH or a matching file " - "in the directory /etc .").arg(text2html(title))); - pageFound=false; - } - else if (foundPages.count()>1) - { - pageFound=false; - //check for the case that there is foo.1 and foo.1.gz found: - // ### TODO make it more generic (other extensions) - if ((foundPages.count()==2) && - (((foundPages[0]+".gz") == foundPages[1]) || - (foundPages[0] == (foundPages[1]+".gz")))) - pageFound=true; - else - outputMatchingPages(foundPages); - } - //yes, we found exactly one man page - - if (pageFound) - { - setResourcePath(m_htmlPath,m_cssPath); - m_outputBuffer.open(IO_WriteOnly); - const TQCString filename=TQFile::encodeName(foundPages[0]); - char *buf = readManPage(filename); - - if (!buf) - { - outputError(i18n("Open of %1 failed.").arg(title)); - finished(); - return; - } - // will call output_real - scan_man_page(buf); - delete [] buf; - - output(0); // flush - - m_outputBuffer.close(); - data(m_outputBuffer.buffer()); - m_outputBuffer.setBuffer(TQByteArray()); - // tell we are done - data(TQByteArray()); - } - finished(); -} - -void MANProtocol::slotGetStdOutput(TDEProcess* /* p */, char *s, int len) -{ - myStdStream += TQString::fromLocal8Bit(s, len); -} - -void MANProtocol::slotGetStdOutputUtf8(TDEProcess* /* p */, char *s, int len) -{ - myStdStream += TQString::fromUtf8(s, len); -} - -char *MANProtocol::readManPage(const char *_filename) -{ - TQCString filename = _filename; - - char *buf = NULL; - - /* Determine type of man page file by checking its path. Determination by - * MIME type with KMimeType doesn't work reliablely. E.g., Solaris 7: - * /usr/man/sman7fs/pcfs.7fs -> text/x-csrc : WRONG - * If the path name constains the string sman, assume that it's SGML and - * convert it to roff format (used on Solaris). */ - //TQString file_mimetype = KMimeType::findByPath(TQString(filename), 0, false)->name(); - if (filename.contains("sman", false)) //file_mimetype == "text/html" || ) - { - myStdStream =TQString::null; - TDEProcess proc; - - /* Determine path to sgml2roff, if not already done. */ - getProgramPath(); - proc << mySgml2RoffPath << filename; - - TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); - proc.start(TDEProcess::Block, TDEProcess::All); - - const TQCString cstr=myStdStream.latin1(); - const int len = cstr.size()-1; - buf = new char[len + 4]; - tqmemmove(buf + 1, cstr.data(), len); - buf[0]=buf[len]='\n'; // Start and end with a end of line - buf[len+1]=buf[len+2]='\0'; // Two additional NUL characters at end - } - else - { - if (TQDir::isRelativePath(filename)) { - kdDebug(7107) << "relative " << filename << endl; - filename = TQDir::cleanDirPath(lastdir + "/" + filename).utf8(); - if (!KStandardDirs::exists(filename)) { // exists perhaps with suffix - lastdir = filename.left(filename.findRev('/')); - TQDir mandir(lastdir); - mandir.setNameFilter(filename.mid(filename.findRev('/') + 1) + ".*"); - filename = lastdir + "/" + TQFile::encodeName(mandir.entryList().first()); - } - kdDebug(7107) << "resolved to " << filename << endl; - } - lastdir = filename.left(filename.findRev('/')); - - myStdStream = TQString::null; - TDEProcess proc; - /* TODO: detect availability of 'man --recode' so that this can go - * upstream */ - proc << "man" << "--recode" << "UTF-8" << filename; - - TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), - this, TQT_SLOT(slotGetStdOutputUtf8(TDEProcess *, char *, int))); - proc.start(TDEProcess::Block, TDEProcess::All); - - const TQCString cstr=myStdStream.utf8(); - const int len = cstr.size()-1; - buf = new char[len + 4]; - tqmemmove(buf + 1, cstr.data(), len); - buf[0]=buf[len]='\n'; // Start and end with a end of line - buf[len+1]=buf[len+2]='\0'; // Two NUL characters at end - } - return buf; -} - - -void MANProtocol::outputError(const TQString& errmsg) -{ - TQByteArray array; - TQTextStream os(array, IO_WriteOnly); - os.setEncoding(TQTextStream::UnicodeUTF8); - - os << "" << endl; - os << "" << endl; - os << "" << i18n("Man output") << "\n" << endl; - if ( !m_manCSSFile.isEmpty() ) - os << "" << endl; - os << "" << endl; - os << i18n("

TDE Man Viewer Error

") << errmsg << "" << endl; - os << "" << endl; - - data(array); -} - -void MANProtocol::outputMatchingPages(const TQStringList &matchingPages) -{ - TQByteArray array; - TQTextStream os(array, IO_WriteOnly); - os.setEncoding(TQTextStream::UnicodeUTF8); - - os << "" << endl; - os << "\n"<" << i18n("Man output") <<"" << endl; - if ( !m_manCSSFile.isEmpty() ) - os << "" << endl; - os << "" <

" << i18n("There is more than one matching man page."); - os << "

\n
    \n"; - - int acckey=1; - for (TQStringList::ConstIterator it = matchingPages.begin(); it != matchingPages.end(); ++it) - { - os<<"
  • "<< *it <<"
    \n
    \n"; - acckey++; - } - os << "
\n"; - os << "
\n"; - os << "

" << i18n("Note: if you read a man page in your language," - " be aware it can contain some mistakes or be obsolete." - " In case of doubt, you should have a look at the English version.") << "

"; - - os << "\n"<" << endl; - os << "" << endl; - os << "" << i18n("UNIX Manual Index") << "" << endl; - if (!m_manCSSFile.isEmpty()) - os << "" << endl; - os << "" << endl; - os << "

" << i18n("UNIX Manual Index") << "

" << endl; - - // ### TODO: why still the environment variable - const TQString sectList = getenv("MANSECT"); - TQStringList sections; - if (sectList.isEmpty()) - sections = buildSectionList(manDirectories()); - else - sections = TQStringList::split(':', sectList); - - os << "" << endl; - - TQStringList::ConstIterator it; - for (it = sections.begin(); it != sections.end(); ++it) - os << "" << endl; - - os << "
" << i18n("Section ") - << *it << "  " << sectionName(*it) << "
" << endl; - - // print footer - os << "" << endl; - - data(array); - finished(); -} - -void MANProtocol::constructPath(TQStringList& constr_path, TQStringList constr_catmanpath) -{ - TQMap manpath_map; - TQMap mandb_map; - - // Add paths from /etc/man.conf - // - // Explicit manpaths may be given by lines starting with "MANPATH" or - // "MANDATORY_MANPATH" (depending on system ?). - // Mappings from $PATH to manpath are given by lines starting with - // "MANPATH_MAP" - - TQRegExp manpath_regex( "^MANPATH\\s" ); - TQRegExp mandatory_regex( "^MANDATORY_MANPATH\\s" ); - TQRegExp manpath_map_regex( "^MANPATH_MAP\\s" ); - TQRegExp mandb_map_regex( "^MANDB_MAP\\s" ); - //TQRegExp section_regex( "^SECTION\\s" ); - TQRegExp space_regex( "\\s+" ); // for parsing manpath map - - TQFile mc("/etc/man.conf"); // Caldera - if (!mc.exists()) - mc.setName("/etc/manpath.config"); // SuSE, Debian - if (!mc.exists()) - mc.setName("/etc/man.config"); // Mandrake - - if (mc.open(IO_ReadOnly)) - { - TQTextStream is(&mc); - is.setEncoding(TQTextStream::Locale); - - while (!is.eof()) - { - const TQString line = is.readLine(); - if ( manpath_regex.search(line, 0) == 0 ) - { - const TQString path = line.mid(8).stripWhiteSpace(); - constr_path += path; - } - else if ( mandatory_regex.search(line, 0) == 0 ) - { - const TQString path = line.mid(18).stripWhiteSpace(); - constr_path += path; - } - else if ( manpath_map_regex.search(line, 0) == 0 ) - { - // The entry is "MANPATH_MAP " - const TQStringList mapping = - TQStringList::split(space_regex, line); - - if ( mapping.count() == 3 ) - { - const TQString dir = TQDir::cleanDirPath( mapping[1] ); - const TQString mandir = TQDir::cleanDirPath( mapping[2] ); - - manpath_map[ dir ] = mandir; - } - } - else if ( mandb_map_regex.search(line, 0) == 0 ) - { - // The entry is "MANDB_MAP " - const TQStringList mapping = - TQStringList::split(space_regex, line); - - if ( mapping.count() == 3 ) - { - const TQString mandir = TQDir::cleanDirPath( mapping[1] ); - const TQString catmandir = TQDir::cleanDirPath( mapping[2] ); - - mandb_map[ mandir ] = catmandir; - } - } - /* sections are not used - else if ( section_regex.find(line, 0) == 0 ) - { - if ( !conf_section.isEmpty() ) - conf_section += ':'; - conf_section += line.mid(8).stripWhiteSpace(); - } - */ - } - mc.close(); - } - - // Default paths - static const char *manpaths[] = { - "/usr/X11/man", - "/usr/X11R6/man", - "/usr/man", - "/usr/local/man", - "/usr/exp/man", - "/usr/openwin/man", - "/usr/dt/man", - "/opt/freetool/man", - "/opt/local/man", - "/usr/tex/man", - "/usr/www/man", - "/usr/lang/man", - "/usr/gnu/man", - "/usr/share/man", - "/usr/motif/man", - "/usr/titools/man", - "/usr/sunpc/man", - "/usr/ncd/man", - "/usr/newsprint/man", - NULL }; - - - int i = 0; - while (manpaths[i]) { - if ( constr_path.findIndex( TQString( manpaths[i] ) ) == -1 ) - constr_path += TQString( manpaths[i] ); - i++; - } - - // Directories in $PATH - // - if a manpath mapping exists, use that mapping - // - if a directory "/man" or "/../man" exists, add it - // to the man path (the actual existence check is done further down) - - if ( ::getenv("PATH") ) { - const TQStringList path = - TQStringList::split( ":", - TQString::fromLocal8Bit( ::getenv("PATH") ) ); - - for ( TQStringList::const_iterator it = path.begin(); - it != path.end(); - ++it ) - { - const TQString dir = TQDir::cleanDirPath( *it ); - TQString mandir = manpath_map[ dir ]; - - if ( !mandir.isEmpty() ) { - // a path mapping exists - if ( constr_path.findIndex( mandir ) == -1 ) - constr_path += mandir; - } - else { - // no manpath mapping, use "/man" and "/../man" - - mandir = dir + TQString( "/man" ); - if ( constr_path.findIndex( mandir ) == -1 ) - constr_path += mandir; - - int pos = dir.findRev( '/' ); - if ( pos > 0 ) { - mandir = dir.left( pos ) + TQString("/man"); - if ( constr_path.findIndex( mandir ) == -1 ) - constr_path += mandir; - } - } - TQString catmandir = mandb_map[ mandir ]; - if ( !mandir.isEmpty() ) - { - if ( constr_catmanpath.findIndex( catmandir ) == -1 ) - constr_catmanpath += catmandir; - } - else - { - // What is the default mapping? - catmandir = mandir; - catmandir.replace("/usr/share/","/var/cache/"); - if ( constr_catmanpath.findIndex( catmandir ) == -1 ) - constr_catmanpath += catmandir; - } - } - } -} - -void MANProtocol::checkManPaths() -{ - static bool inited = false; - - if (inited) - return; - - inited = true; - - const TQString manpath_env = TQString::fromLocal8Bit( ::getenv("MANPATH") ); - //TQString mansect_env = TQString::fromLocal8Bit( ::getenv("MANSECT") ); - - // Decide if $MANPATH is enough on its own or if it should be merged - // with the constructed path. - // A $MANPATH starting or ending with ":", or containing "::", - // should be merged with the constructed path. - - bool construct_path = false; - - if ( manpath_env.isEmpty() - || manpath_env[0] == ':' - || manpath_env[manpath_env.length()-1] == ':' - || manpath_env.contains( "::" ) ) - { - construct_path = true; // need to read config file - } - - // Constucted man path -- consists of paths from - // /etc/man.conf - // default dirs - // $PATH - TQStringList constr_path; - TQStringList constr_catmanpath; // catmanpath - - TQString conf_section; - - if ( construct_path ) - { - constructPath(constr_path, constr_catmanpath); - } - - m_mandbpath=constr_catmanpath; - - // Merge $MANPATH with the constructed path to form the - // actual manpath. - // - // The merging syntax with ":" and "::" in $MANPATH will be - // satisfied if any empty string in path_list_env (there - // should be 1 or 0) is replaced by the constructed path. - - const TQStringList path_list_env = TQStringList::split( ':', manpath_env , true ); - - for ( TQStringList::const_iterator it = path_list_env.begin(); - it != path_list_env.end(); - ++it ) - { - struct stat sbuf; - - TQString dir = (*it); - - if ( !dir.isEmpty() ) { - // Add dir to the man path if it exists - if ( m_manpath.findIndex( dir ) == -1 ) { - if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 - && S_ISDIR( sbuf.st_mode ) ) - { - m_manpath += dir; - } - } - } - else { - // Insert constructed path ($MANPATH was empty, or - // there was a ":" at an end or "::") - - for ( TQStringList::Iterator it2 = constr_path.begin(); - it2 != constr_path.end(); - it2++ ) - { - dir = (*it2); - - if ( !dir.isEmpty() ) { - if ( m_manpath.findIndex( dir ) == -1 ) { - if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 - && S_ISDIR( sbuf.st_mode ) ) - { - m_manpath += dir; - } - } - } - } - } - } - -/* sections are not used - // Sections - TQStringList m_mansect = TQStringList::split( ':', mansect_env, true ); - - const char* default_sect[] = - { "1", "2", "3", "4", "5", "6", "7", "8", "9", "n", 0L }; - - for ( int i = 0; default_sect[i] != 0L; i++ ) - if ( m_mansect.findIndex( TQString( default_sect[i] ) ) == -1 ) - m_mansect += TQString( default_sect[i] ); -*/ - -} - - -//#define _USE_OLD_CODE - -#ifdef _USE_OLD_CODE -#warning "using old code" -#else - -// Define this, if you want to compile with qsort from stdlib.h -// else the Qt Heapsort will be used. -// Note, qsort seems to be a bit faster (~10%) on a large man section -// eg. man section 3 -#define _USE_QSORT - -// Setup my own structure, with char pointers. -// from now on only pointers are copied, no strings -// -// containing the whole path string, -// the beginning of the man page name -// and the length of the name -struct man_index_t { - char *manpath; // the full path including man file - const char *manpage_begin; // pointer to the begin of the man file name in the path - int manpage_len; // len of the man file name -}; -typedef man_index_t *man_index_ptr; - -#ifdef _USE_QSORT -int compare_man_index(const void *s1, const void *s2) -{ - struct man_index_t *m1 = *(struct man_index_t **)s1; - struct man_index_t *m2 = *(struct man_index_t **)s2; - int i; - // Compare the names of the pages - // with the shorter length. - // Man page names are not '\0' terminated, so - // this is a bit tricky - if ( m1->manpage_len > m2->manpage_len) - { - i = tqstrnicmp( m1->manpage_begin, - m2->manpage_begin, - m2->manpage_len); - if (!i) - return 1; - return i; - } - - if ( m1->manpage_len < m2->manpage_len) - { - i = tqstrnicmp( m1->manpage_begin, - m2->manpage_begin, - m1->manpage_len); - if (!i) - return -1; - return i; - } - - return tqstrnicmp( m1->manpage_begin, - m2->manpage_begin, - m1->manpage_len); -} - -#else /* !_USE_QSORT */ -#warning using heapsort -// Set up my own man page list, -// with a special compare function to sort itself -typedef TQPtrList QManIndexListBase; -typedef TQPtrListIterator QManIndexListIterator; - -class QManIndexList : public QManIndexListBase -{ -public: -private: - int compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 ) - { - struct man_index_t *m1 = (struct man_index_t *)s1; - struct man_index_t *m2 = (struct man_index_t *)s2; - int i; - // compare the names of the pages - // with the shorter length - if (m1->manpage_len > m2->manpage_len) - { - i = tqstrnicmp(m1->manpage_begin, - m2->manpage_begin, - m2->manpage_len); - if (!i) - return 1; - return i; - } - - if (m1->manpage_len > m2->manpage_len) - { - - i = tqstrnicmp(m1->manpage_begin, - m2->manpage_begin, - m1->manpage_len); - if (!i) - return -1; - return i; - } - - return tqstrnicmp(m1->manpage_begin, - m2->manpage_begin, - m1->manpage_len); - } -}; - -#endif /* !_USE_QSORT */ -#endif /* !_USE_OLD_CODE */ - - - - -void MANProtocol::showIndex(const TQString& section) -{ - TQByteArray array; - TQTextStream os(array, IO_WriteOnly); - os.setEncoding(TQTextStream::UnicodeUTF8); - - // print header - os << "" << endl; - os << "" << endl; - os << "" << i18n("UNIX Manual Index") << "" << endl; - if ( !m_manCSSFile.isEmpty() ) - os << "" << endl; - os << "" << endl; - os << "
" << endl; - os << "

" << i18n( "Index for Section %1: %2").arg(section).arg(sectionName(section)) << "

" << endl; - - // compose list of search paths ------------------------------------------------------------- - - checkManPaths(); - infoMessage(i18n("Generating Index")); - - // search for the man pages - TQStringList pages = findPages( section, TQString::null ); - - TQMap indexmap = buildIndexMap(section); - - // print out the list - os << "" << endl; - -#ifdef _USE_OLD_CODE - pages.sort(); - - TQMap pagemap; - - TQStringList::ConstIterator page; - for (page = pages.begin(); page != pages.end(); ++page) - { - TQString fileName = *page; - - stripExtension( &fileName ); - - pos = fileName.findRev('/'); - if (pos > 0) - fileName = fileName.mid(pos+1); - - if (!fileName.isEmpty()) - pagemap[fileName] = *page; - - } - - for (TQMap::ConstIterator it = pagemap.begin(); - it != pagemap.end(); ++it) - { - os << "" << endl; - } - -#else /* ! _USE_OLD_CODE */ - -#ifdef _USE_QSORT - - int listlen = pages.count(); - man_index_ptr *indexlist = new man_index_ptr[listlen]; - listlen = 0; - -#else /* !_USE_QSORT */ - - QManIndexList manpages; - manpages.setAutoDelete(TRUE); - -#endif /* _USE_QSORT */ - - TQStringList::const_iterator page; - for (page = pages.begin(); page != pages.end(); ++page) - { - // I look for the beginning of the man page name - // i.e. "bla/pagename.3.gz" by looking for the last "/" - // Then look for the end of the name by searching backwards - // for the last ".", not counting zip extensions. - // If the len of the name is >0, - // store it in the list structure, to be sorted later - - char *manpage_end; - struct man_index_t *manindex = new man_index_t; - manindex->manpath = strdup((*page).utf8()); - - manindex->manpage_begin = strrchr(manindex->manpath, '/'); - if (manindex->manpage_begin) - { - manindex->manpage_begin++; - assert(manindex->manpage_begin >= manindex->manpath); - } - else - { - manindex->manpage_begin = manindex->manpath; - assert(manindex->manpage_begin >= manindex->manpath); - } - - // Skip extension ".section[.gz]" - - char *begin = (char*)(manindex->manpage_begin); - int len = strlen( begin ); - char *end = begin+(len-1); - - if ( len >= 3 && strcmp( end-2, ".gz" ) == 0 ) - end -= 3; - else if ( len >= 2 && strcmp( end-1, ".Z" ) == 0 ) - end -= 2; - else if ( len >= 2 && strcmp( end-1, ".z" ) == 0 ) - end -= 2; - else if ( len >= 4 && strcmp( end-3, ".bz2" ) == 0 ) - end -= 4; - - while ( end >= begin && *end != '.' ) - end--; - - if ( end < begin ) - manpage_end = 0; - else - manpage_end = end; - - if (NULL == manpage_end) - { - // no '.' ending ??? - // set the pointer past the end of the filename - manindex->manpage_len = (*page).length(); - manindex->manpage_len -= (manindex->manpage_begin - manindex->manpath); - assert(manindex->manpage_len >= 0); - } - else - { - manindex->manpage_len = (manpage_end - manindex->manpage_begin); - assert(manindex->manpage_len >= 0); - } - - if (0 < manindex->manpage_len) - { - -#ifdef _USE_QSORT - - indexlist[listlen] = manindex; - listlen++; - -#else /* !_USE_QSORT */ - - manpages.append(manindex); - -#endif /* _USE_QSORT */ - - } - } - - // - // Now do the sorting on the page names - // and the printout afterwards - // While printing avoid duplicate man page names - // - - struct man_index_t dummy_index = {0l,0l,0}; - struct man_index_t *last_index = &dummy_index; - -#ifdef _USE_QSORT - - // sort and print - qsort(indexlist, listlen, sizeof(struct man_index_t *), compare_man_index); - - TQChar firstchar, tmp; - TQString indexLine="
\n"; - if (indexlist[0]->manpage_len>0) - { - firstchar=TQChar((indexlist[0]->manpage_begin)[0]).lower(); - - const TQString appendixstr = TQString( - " [%3]\n" - ).arg(firstchar).arg(firstchar).arg(firstchar); - indexLine.append(appendixstr); - } - os << "
" << endl; - - for (int i=0; imanpage_begin" has not, - // so do compare at most "manindex->manpage_len" of the strings. - if (last_index->manpage_len == manindex->manpage_len && - !tqstrncmp(last_index->manpage_begin, - manindex->manpage_begin, - manindex->manpage_len) - ) - { - continue; - } - - tmp=TQChar((manindex->manpage_begin)[0]).lower(); - if (firstchar != tmp) - { - firstchar = tmp; - os << "" << endl; - - const TQString appendixstr = TQString( - " [%3]\n" - ).arg(firstchar).arg(firstchar).arg(firstchar); - indexLine.append(appendixstr); - } - os << "" << endl; - last_index = manindex; - } - indexLine.append(""); - - for (int i=0; imanpath); // allocated by strdup - delete indexlist[i]; - } - - delete [] indexlist; - -#else /* !_USE_QSORT */ - - manpages.sort(); // using - - for (QManIndexListIterator mit(manpages); - mit.current(); - ++mit ) - { - struct man_index_t *manindex = mit.current(); - - // tqstrncmp(): - // "last_man" has already a \0 string ending, but - // "manindex->manpage_begin" has not, - // so do compare at most "manindex->manpage_len" of the strings. - if (last_index->manpage_len == manindex->manpage_len && - !tqstrncmp(last_index->manpage_begin, - manindex->manpage_begin, - manindex->manpage_len) - ) - { - continue; - } - - os << "" << endl; - last_index = manindex; - } -#endif /* _USE_QSORT */ -#endif /* _USE_OLD_CODE */ - - os << "
\n" - << it.key() << "  " - << (indexmap.contains(it.key()) ? indexmap[it.key()] : "" ) - << "
\n " << firstchar <<"\n
\n " << firstchar << "\n
manpath << "\">\n"; - - ((char *)manindex->manpage_begin)[manindex->manpage_len] = '\0'; - os << manindex->manpage_begin - << "  " - << (indexmap.contains(manindex->manpage_begin) ? indexmap[manindex->manpage_begin] : "" ) - << "
manpath << "\">\n"; - - manindex->manpage_begin[manindex->manpage_len] = '\0'; - os << manindex->manpage_begin - << "  " - << (indexmap.contains(manindex->manpage_begin) ? indexmap[manindex->manpage_begin] : "" ) - << "
" << endl; - - os << indexLine << endl; - - // print footer - os << "" << endl; - - infoMessage(TQString::null); - mimeType("text/html"); - data(array); - finished(); -} - -void MANProtocol::listDir(const KURL &url) -{ - kdDebug( 7107 ) << "ENTER listDir: " << url.prettyURL() << endl; - - TQString title; - TQString section; - - if ( !parseUrl(url.path(), title, section) ) { - error( TDEIO::ERR_MALFORMED_URL, url.url() ); - return; - } - - TQStringList list = findPages( section, TQString::null, false ); - - UDSEntryList uds_entry_list; - UDSEntry uds_entry; - UDSAtom uds_atom; - - uds_atom.m_uds = TDEIO::UDS_NAME; // we only do names... - uds_entry.append( uds_atom ); - - TQStringList::Iterator it = list.begin(); - TQStringList::Iterator end = list.end(); - - for ( ; it != end; ++it ) { - stripExtension( &(*it) ); - - uds_entry[0].m_str = *it; - uds_entry_list.append( uds_entry ); - } - - listEntries( uds_entry_list ); - finished(); -} - -void MANProtocol::getProgramPath() -{ - if (!mySgml2RoffPath.isEmpty()) - return; - - mySgml2RoffPath = TDEGlobal::dirs()->findExe("sgml2roff"); - if (!mySgml2RoffPath.isEmpty()) - return; - - /* sgml2roff isn't found in PATH. Check some possible locations where it may be found. */ - mySgml2RoffPath = TDEGlobal::dirs()->findExe("sgml2roff", TQString(SGML2ROFF_DIRS)); - if (!mySgml2RoffPath.isEmpty()) - return; - - /* Cannot find sgml2roff programm: */ - outputError(i18n("Could not find the sgml2roff program on your system. Please install it, if necessary, and extend the search path by adjusting the environment variable PATH before starting TDE.")); - finished(); - exit(); -} diff --git a/tdeioslave/man/kio_man.css b/tdeioslave/man/kio_man.css deleted file mode 100644 index 8a9f378bc..000000000 --- a/tdeioslave/man/kio_man.css +++ /dev/null @@ -1,21 +0,0 @@ -body {background-color:#fffff} - -/*for the list of one manpage section*/ -.secidxshort { - display:block; - position:absolute;overflow:auto; - top:0px;bottom:95%;left:0;right:0; -} -.secidxmain { -/*misfortunately accessing anchors in a scrollview - doesn't seem to work yet with konqi, so:*/ -/* - position:absolute;overflow:auto; - top:5%;bottom:0;left:0;right:0; -*/ -} -.secidxnextletter { - font-size:larger; - border-bottom:1px solid black; - text-align:center -} diff --git a/tdeioslave/man/kio_man.h b/tdeioslave/man/kio_man.h deleted file mode 100644 index 829a07964..000000000 --- a/tdeioslave/man/kio_man.h +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (c) 2000 Matthias Hoelzer-Kluepfel - - - 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_man_h__ -#define __kio_man_h__ - - -#include -#include -#include -#include -#include - - -#include -#include - - -class MANProtocol : public TQObject, public TDEIO::SlaveBase -{ - Q_OBJECT - -public: - - MANProtocol(const TQCString &pool_socket, const TQCString &app_socket); - virtual ~MANProtocol(); - - virtual void get(const KURL& url); - virtual void stat(const KURL& url); - - virtual void mimetype(const KURL &url); - virtual void listDir(const KURL &url); - - void outputError(const TQString& errmsg); - void outputMatchingPages(const TQStringList &matchingPages); - - void showMainIndex(); - void showIndex(const TQString& section); - - // the following two functions are the interface to man2html - void output(const char *insert); - char *readManPage(const char *filename); - - static MANProtocol *self(); - -private slots: - void slotGetStdOutput(TDEProcess*, char*, int); - void slotGetStdOutputUtf8(TDEProcess*, char*, int); - -private: - void checkManPaths(); - TQStringList manDirectories(); - TQMap buildIndexMap(const TQString& section); - bool addWhatIs(TQMap& i, const TQString& f, const TQString& mark); - void parseWhatIs( TQMap &i, TQTextStream &t, const TQString &mark ); - TQStringList findPages(const TQString& section, - const TQString &title, - bool full_path = true); - - void addToBuffer(const char *buffer, int buflen); - TQString pageName(const TQString& page) const; - TQStringList buildSectionList(const TQStringList& dirs) const; - void constructPath(TQStringList& constr_path, TQStringList constr_catmanpath); -private: - static MANProtocol *_self; - TQCString lastdir; - - void findManPagesInSection(const TQString &dir, const TQString &title, bool full_path, TQStringList &list); - TQStringList m_manpath; ///< Path of man directories - TQStringList m_mandbpath; ///< Path of catman directories - TQStringList section_names; - - TQString myStdStream; - TQString mySgml2RoffPath; - void getProgramPath(); - - TQCString m_htmlPath; ///< Path to TDE resources, encoded for HTML - TQCString m_cssPath; ///< Path to TDE resources, encoded for CSS - TQBuffer m_outputBuffer; ///< Buffer for the output - TQString m_manCSSFile; ///< Path to kio_man.css -}; - - -#endif diff --git a/tdeioslave/man/kio_man_test.cpp b/tdeioslave/man/kio_man_test.cpp deleted file mode 100644 index a181c47b3..000000000 --- a/tdeioslave/man/kio_man_test.cpp +++ /dev/null @@ -1,38 +0,0 @@ - - -#include - -#include "kio_man.h" - - -#include -#include - - -class kio_man_test : public MANProtocol -{ - Q_OBJECT - -public: - kio_man_test(const TQCString &pool_socket, const TQCString &app_socket); - -protected: - virtual void data(int); - -}; - - - - - -int main(int argc, char **argv) -{ - TDEApplication a( argc, argv , "p2"); - - MANProtocol testproto("/tmp/tdeiotest.in", "/tmp/tdeiotest.out"); - testproto.showIndex("3"); - - return 0; -} - - diff --git a/tdeioslave/man/man.protocol b/tdeioslave/man/man.protocol index 555970fdc..37a57cec4 100644 --- a/tdeioslave/man/man.protocol +++ b/tdeioslave/man/man.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_man +exec=tdeio_man protocol=man input=none output=filesystem diff --git a/tdeioslave/man/man2html.cpp b/tdeioslave/man/man2html.cpp index ec46b2d3d..577f7d53a 100644 --- a/tdeioslave/man/man2html.cpp +++ b/tdeioslave/man/man2html.cpp @@ -4073,7 +4073,7 @@ static char *scan_request(char *c) // Most English man pages are in ISO-8859-1 out_html("\n"); #else - // kio_man transforms from local to UTF-8 + // tdeio_man transforms from local to UTF-8 out_html("\n"); diff --git a/tdeioslave/man/tdeio_man.cpp b/tdeioslave/man/tdeio_man.cpp new file mode 100644 index 000000000..4c4f1945c --- /dev/null +++ b/tdeioslave/man/tdeio_man.cpp @@ -0,0 +1,1533 @@ +/* This file is part of the KDE libraries + Copyright (c) 2000 Matthias Hoelzer-Kluepfel + + 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "tdeio_man.h" +#include "tdeio_man.moc" +#include "man2html.h" +#include +#include +#include + +using namespace TDEIO; + +MANProtocol *MANProtocol::_self = 0; + +#define SGML2ROFF_DIRS "/usr/lib/sgml" + +/* + * Drop trailing ".section[.gz]" from name + */ +static +void stripExtension( TQString *name ) +{ + int pos = name->length(); + + if ( name->find(".gz", -3) != -1 ) + pos -= 3; + else if ( name->find(".z", -2, false) != -1 ) + pos -= 2; + else if ( name->find(".bz2", -4) != -1 ) + pos -= 4; + else if ( name->find(".bz", -3) != -1 ) + pos -= 3; + + if ( pos > 0 ) + pos = name->findRev('.', pos-1); + + if ( pos > 0 ) + name->truncate( pos ); +} + +static +bool parseUrl(const TQString& _url, TQString &title, TQString §ion) +{ + section = TQString::null; + + TQString url = _url; + if (url.at(0) == '/') { + if (KStandardDirs::exists(url)) { + title = url; + return true; + } else + { + // If the directory does not exist, then it is perhaps a normal man page + kdDebug(7107) << url << " does not exist" << endl; + } + } + + while (url.at(0) == '/') + url.remove(0,1); + + title = url; + + int pos = url.find('('); + if (pos < 0) + return true; + + title = title.left(pos); + + section = url.mid(pos+1); + section = section.left(section.length()-1); + + return true; +} + + +MANProtocol::MANProtocol(const TQCString &pool_socket, const TQCString &app_socket) + : TQObject(), SlaveBase("man", pool_socket, app_socket) +{ + assert(!_self); + _self = this; + const TQString common_dir = TDEGlobal::dirs()->findResourceDir( "html", "en/common/kde-common.css" ); + const TQString strPath=TQString( "file:%1/en/common" ).arg( common_dir ); + m_htmlPath=strPath.local8Bit(); // ### TODO encode for HTML + m_cssPath=strPath.local8Bit(); // ### TODO encode for CSS + section_names << "1" << "2" << "3" << "3n" << "3p" << "4" << "5" << "6" << "7" + << "8" << "9" << "l" << "n"; + m_manCSSFile = locate( "data", "tdeio_man/tdeio_man.css" ); +} + +MANProtocol *MANProtocol::self() { return _self; } + +MANProtocol::~MANProtocol() +{ + _self = 0; +} + +void MANProtocol::parseWhatIs( TQMap &i, TQTextStream &t, const TQString &mark ) +{ + TQRegExp re( mark ); + TQString l; + while ( !t.atEnd() ) + { + l = t.readLine(); + int pos = re.search( l ); + if (pos != -1) + { + TQString names = l.left(pos); + TQString descr = l.mid(pos + re.matchedLength()); + while ((pos = names.find(",")) != -1) + { + i[names.left(pos++)] = descr; + while (names[pos] == ' ') + pos++; + names = names.mid(pos); + } + i[names] = descr; + } + } +} + +bool MANProtocol::addWhatIs(TQMap &i, const TQString &name, const TQString &mark) +{ + TQFile f(name); + if (!f.open(IO_ReadOnly)) + return false; + TQTextStream t(&f); + parseWhatIs( i, t, mark ); + return true; +} + +TQMap MANProtocol::buildIndexMap(const TQString §ion) +{ + TQMap i; + TQStringList man_dirs = manDirectories(); + // Supplementary places for whatis databases + man_dirs += m_mandbpath; + if (man_dirs.find("/var/cache/man")==man_dirs.end()) + man_dirs << "/var/cache/man"; + if (man_dirs.find("/var/catman")==man_dirs.end()) + man_dirs << "/var/catman"; + + TQStringList names; + names << "whatis.db" << "whatis"; + TQString mark = "\\s+\\(" + section + "[a-z]*\\)\\s+-\\s+"; + + for ( TQStringList::ConstIterator it_dir = man_dirs.begin(); + it_dir != man_dirs.end(); + ++it_dir ) + { + if ( TQFile::exists( *it_dir ) ) { + TQStringList::ConstIterator it_name; + for ( it_name = names.begin(); + it_name != names.end(); + it_name++ ) + { + if (addWhatIs(i, (*it_dir) + "/" + (*it_name), mark)) + break; + } + if ( it_name == names.end() ) { + TDEProcess proc; + proc << "whatis" << "-M" << (*it_dir) << "-w" << "*"; + myStdStream = TQString::null; + connect( &proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int ) ), + TQT_SLOT( slotGetStdOutput( TDEProcess *, char *, int ) ) ); + proc.start( TDEProcess::Block, TDEProcess::Stdout ); + TQTextStream t( &myStdStream, IO_ReadOnly ); + parseWhatIs( i, t, mark ); + } + } + } + return i; +} + +TQStringList MANProtocol::manDirectories() +{ + checkManPaths(); + // + // Build a list of man directories including translations + // + TQStringList man_dirs; + + for ( TQStringList::ConstIterator it_dir = m_manpath.begin(); + it_dir != m_manpath.end(); + it_dir++ ) + { + // Translated pages in "/" if the directory + // exists + TQStringList languages = TDEGlobal::locale()->languageList(); + + for (TQStringList::ConstIterator it_lang = languages.begin(); + it_lang != languages.end(); + it_lang++ ) + { + if ( !(*it_lang).isEmpty() && (*it_lang) != TQString("C") ) { + TQString dir = (*it_dir) + '/' + (*it_lang); + + struct stat sbuf; + + if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 + && S_ISDIR( sbuf.st_mode ) ) + { + const TQString p = TQDir(dir).canonicalPath(); + if (!man_dirs.contains(p)) man_dirs += p; + } + } + } + + // Untranslated pages in "" + const TQString p = TQDir(*it_dir).canonicalPath(); + if (!man_dirs.contains(p)) man_dirs += p; + } + return man_dirs; +} + +TQStringList MANProtocol::findPages(const TQString &_section, + const TQString &title, + bool full_path) +{ + TQString section = _section; + + TQStringList list; + + // kdDebug() << "findPages '" << section << "' '" << title << "'\n"; + if (title.at(0) == '/') { + list.append(title); + return list; + } + + const TQString star( "*" ); + + // + // Find man sections in this directory + // + TQStringList sect_list; + if ( section.isEmpty() ) + section = star; + + if ( section != star ) + { + // + // Section given as argument + // + sect_list += section; + while (section.at(section.length() - 1).isLetter()) { + section.truncate(section.length() - 1); + sect_list += section; + } + } else { + sect_list += section; + } + + TQStringList man_dirs = manDirectories(); + + // + // Find man pages in the sections listed above + // + for ( TQStringList::ConstIterator it_sect = sect_list.begin(); + it_sect != sect_list.end(); + it_sect++ ) + { + TQString it_real = (*it_sect).lower(); + // + // Find pages + // + for ( TQStringList::ConstIterator it_dir = man_dirs.begin(); + it_dir != man_dirs.end(); + it_dir++ ) + { + TQString man_dir = (*it_dir); + + // + // Sections = all sub directories "man*" and "sman*" + // + DIR *dp = ::opendir( TQFile::encodeName( man_dir ) ); + + if ( !dp ) + continue; + + struct dirent *ep; + + const TQString man = TQString("man"); + const TQString sman = TQString("sman"); + + while ( (ep = ::readdir( dp )) != 0L ) { + const TQString file = TQFile::decodeName( ep->d_name ); + TQString sect = TQString::null; + + if ( file.startsWith( man ) ) + sect = file.mid(3); + else if (file.startsWith(sman)) + sect = file.mid(4); + + if (sect.lower()==it_real) it_real = sect; + + // Only add sect if not already contained, avoid duplicates + if (!sect_list.contains(sect) && _section.isEmpty()) { + kdDebug() << "another section " << sect << endl; + sect_list += sect; + } + } + + ::closedir( dp ); + + if ( *it_sect != star ) { // in that case we only look around for sections + const TQString dir = man_dir + TQString("/man") + (it_real) + '/'; + const TQString sdir = man_dir + TQString("/sman") + (it_real) + '/'; + + findManPagesInSection(dir, title, full_path, list); + findManPagesInSection(sdir, title, full_path, list); + } + } + } + +// kdDebug(7107) << "finished " << list << " " << sect_list << endl; + + return list; +} + +void MANProtocol::findManPagesInSection(const TQString &dir, const TQString &title, bool full_path, TQStringList &list) +{ + kdDebug() << "findManPagesInSection " << dir << " " << title << endl; + bool title_given = !title.isEmpty(); + + DIR *dp = ::opendir( TQFile::encodeName( dir ) ); + + if ( !dp ) + return; + + struct dirent *ep; + + while ( (ep = ::readdir( dp )) != 0L ) { + if ( ep->d_name[0] != '.' ) { + + TQString name = TQFile::decodeName( ep->d_name ); + + // check title if we're looking for a specific page + if ( title_given ) { + if ( !name.startsWith( title ) ) { + continue; + } + else { + // beginning matches, do a more thorough check... + TQString tmp_name = name; + stripExtension( &tmp_name ); + if ( tmp_name != title ) + continue; + } + } + + if ( full_path ) + name.prepend( dir ); + + list += name ; + } + } + ::closedir( dp ); +} + +void MANProtocol::output(const char *insert) +{ + if (insert) + { + m_outputBuffer.writeBlock(insert,strlen(insert)); + } + if (!insert || m_outputBuffer.at() >= 2048) + { + m_outputBuffer.close(); + data(m_outputBuffer.buffer()); + m_outputBuffer.setBuffer(TQByteArray()); + m_outputBuffer.open(IO_WriteOnly); + } +} + +// called by man2html +char *read_man_page(const char *filename) +{ + return MANProtocol::self()->readManPage(filename); +} + +// called by man2html +void output_real(const char *insert) +{ + MANProtocol::self()->output(insert); +} + +static TQString text2html(const TQString& txt) +{ + TQString reply = txt; + + reply = reply.replace('&', "&"); + reply = reply.replace('<', "<"); + reply = reply.replace('>', ">"); + reply = reply.replace('"', "&dquot;"); + reply = reply.replace('\'', """); + return reply; +} + +void MANProtocol::get(const KURL& url ) +{ + kdDebug(7107) << "GET " << url.url() << endl; + + TQString title, section; + + if (!parseUrl(url.path(), title, section)) + { + showMainIndex(); + return; + } + + // see if an index was requested + if (url.query().isEmpty() && (title.isEmpty() || title == "/" || title == ".")) + { + if (section == "index" || section.isEmpty()) + showMainIndex(); + else + showIndex(section); + return; + } + + // tell the mimetype + mimeType("text/html"); + + const TQStringList foundPages=findPages(section, title); + bool pageFound=true; + if (foundPages.isEmpty()) + { + outputError(i18n("No man page matching to %1 found.

" + "Check that you have not mistyped the name of the page that you want.\n" + "Be careful that you must take care about upper case and lower case characters!
" + "If everything looks correct, then perhaps you need to set a better search path " + "for man pages, be it by the environment variable MANPATH or a matching file " + "in the directory /etc .").arg(text2html(title))); + pageFound=false; + } + else if (foundPages.count()>1) + { + pageFound=false; + //check for the case that there is foo.1 and foo.1.gz found: + // ### TODO make it more generic (other extensions) + if ((foundPages.count()==2) && + (((foundPages[0]+".gz") == foundPages[1]) || + (foundPages[0] == (foundPages[1]+".gz")))) + pageFound=true; + else + outputMatchingPages(foundPages); + } + //yes, we found exactly one man page + + if (pageFound) + { + setResourcePath(m_htmlPath,m_cssPath); + m_outputBuffer.open(IO_WriteOnly); + const TQCString filename=TQFile::encodeName(foundPages[0]); + char *buf = readManPage(filename); + + if (!buf) + { + outputError(i18n("Open of %1 failed.").arg(title)); + finished(); + return; + } + // will call output_real + scan_man_page(buf); + delete [] buf; + + output(0); // flush + + m_outputBuffer.close(); + data(m_outputBuffer.buffer()); + m_outputBuffer.setBuffer(TQByteArray()); + // tell we are done + data(TQByteArray()); + } + finished(); +} + +void MANProtocol::slotGetStdOutput(TDEProcess* /* p */, char *s, int len) +{ + myStdStream += TQString::fromLocal8Bit(s, len); +} + +void MANProtocol::slotGetStdOutputUtf8(TDEProcess* /* p */, char *s, int len) +{ + myStdStream += TQString::fromUtf8(s, len); +} + +char *MANProtocol::readManPage(const char *_filename) +{ + TQCString filename = _filename; + + char *buf = NULL; + + /* Determine type of man page file by checking its path. Determination by + * MIME type with KMimeType doesn't work reliablely. E.g., Solaris 7: + * /usr/man/sman7fs/pcfs.7fs -> text/x-csrc : WRONG + * If the path name constains the string sman, assume that it's SGML and + * convert it to roff format (used on Solaris). */ + //TQString file_mimetype = KMimeType::findByPath(TQString(filename), 0, false)->name(); + if (filename.contains("sman", false)) //file_mimetype == "text/html" || ) + { + myStdStream =TQString::null; + TDEProcess proc; + + /* Determine path to sgml2roff, if not already done. */ + getProgramPath(); + proc << mySgml2RoffPath << filename; + + TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutput(TDEProcess *, char *, int))); + proc.start(TDEProcess::Block, TDEProcess::All); + + const TQCString cstr=myStdStream.latin1(); + const int len = cstr.size()-1; + buf = new char[len + 4]; + tqmemmove(buf + 1, cstr.data(), len); + buf[0]=buf[len]='\n'; // Start and end with a end of line + buf[len+1]=buf[len+2]='\0'; // Two additional NUL characters at end + } + else + { + if (TQDir::isRelativePath(filename)) { + kdDebug(7107) << "relative " << filename << endl; + filename = TQDir::cleanDirPath(lastdir + "/" + filename).utf8(); + if (!KStandardDirs::exists(filename)) { // exists perhaps with suffix + lastdir = filename.left(filename.findRev('/')); + TQDir mandir(lastdir); + mandir.setNameFilter(filename.mid(filename.findRev('/') + 1) + ".*"); + filename = lastdir + "/" + TQFile::encodeName(mandir.entryList().first()); + } + kdDebug(7107) << "resolved to " << filename << endl; + } + lastdir = filename.left(filename.findRev('/')); + + myStdStream = TQString::null; + TDEProcess proc; + /* TODO: detect availability of 'man --recode' so that this can go + * upstream */ + proc << "man" << "--recode" << "UTF-8" << filename; + + TQApplication::connect(&proc, TQT_SIGNAL(receivedStdout (TDEProcess *, char *, int)), + this, TQT_SLOT(slotGetStdOutputUtf8(TDEProcess *, char *, int))); + proc.start(TDEProcess::Block, TDEProcess::All); + + const TQCString cstr=myStdStream.utf8(); + const int len = cstr.size()-1; + buf = new char[len + 4]; + tqmemmove(buf + 1, cstr.data(), len); + buf[0]=buf[len]='\n'; // Start and end with a end of line + buf[len+1]=buf[len+2]='\0'; // Two NUL characters at end + } + return buf; +} + + +void MANProtocol::outputError(const TQString& errmsg) +{ + TQByteArray array; + TQTextStream os(array, IO_WriteOnly); + os.setEncoding(TQTextStream::UnicodeUTF8); + + os << "" << endl; + os << "" << endl; + os << "" << i18n("Man output") << "\n" << endl; + if ( !m_manCSSFile.isEmpty() ) + os << "" << endl; + os << "" << endl; + os << i18n("

TDE Man Viewer Error

") << errmsg << "" << endl; + os << "" << endl; + + data(array); +} + +void MANProtocol::outputMatchingPages(const TQStringList &matchingPages) +{ + TQByteArray array; + TQTextStream os(array, IO_WriteOnly); + os.setEncoding(TQTextStream::UnicodeUTF8); + + os << "" << endl; + os << "\n"<" << i18n("Man output") <<"" << endl; + if ( !m_manCSSFile.isEmpty() ) + os << "" << endl; + os << "" <

" << i18n("There is more than one matching man page."); + os << "

\n
    \n"; + + int acckey=1; + for (TQStringList::ConstIterator it = matchingPages.begin(); it != matchingPages.end(); ++it) + { + os<<"
  • "<< *it <<"
    \n
    \n"; + acckey++; + } + os << "
\n"; + os << "
\n"; + os << "

" << i18n("Note: if you read a man page in your language," + " be aware it can contain some mistakes or be obsolete." + " In case of doubt, you should have a look at the English version.") << "

"; + + os << "\n"<" << endl; + os << "" << endl; + os << "" << i18n("UNIX Manual Index") << "" << endl; + if (!m_manCSSFile.isEmpty()) + os << "" << endl; + os << "" << endl; + os << "

" << i18n("UNIX Manual Index") << "

" << endl; + + // ### TODO: why still the environment variable + const TQString sectList = getenv("MANSECT"); + TQStringList sections; + if (sectList.isEmpty()) + sections = buildSectionList(manDirectories()); + else + sections = TQStringList::split(':', sectList); + + os << "" << endl; + + TQStringList::ConstIterator it; + for (it = sections.begin(); it != sections.end(); ++it) + os << "" << endl; + + os << "
" << i18n("Section ") + << *it << "  " << sectionName(*it) << "
" << endl; + + // print footer + os << "" << endl; + + data(array); + finished(); +} + +void MANProtocol::constructPath(TQStringList& constr_path, TQStringList constr_catmanpath) +{ + TQMap manpath_map; + TQMap mandb_map; + + // Add paths from /etc/man.conf + // + // Explicit manpaths may be given by lines starting with "MANPATH" or + // "MANDATORY_MANPATH" (depending on system ?). + // Mappings from $PATH to manpath are given by lines starting with + // "MANPATH_MAP" + + TQRegExp manpath_regex( "^MANPATH\\s" ); + TQRegExp mandatory_regex( "^MANDATORY_MANPATH\\s" ); + TQRegExp manpath_map_regex( "^MANPATH_MAP\\s" ); + TQRegExp mandb_map_regex( "^MANDB_MAP\\s" ); + //TQRegExp section_regex( "^SECTION\\s" ); + TQRegExp space_regex( "\\s+" ); // for parsing manpath map + + TQFile mc("/etc/man.conf"); // Caldera + if (!mc.exists()) + mc.setName("/etc/manpath.config"); // SuSE, Debian + if (!mc.exists()) + mc.setName("/etc/man.config"); // Mandrake + + if (mc.open(IO_ReadOnly)) + { + TQTextStream is(&mc); + is.setEncoding(TQTextStream::Locale); + + while (!is.eof()) + { + const TQString line = is.readLine(); + if ( manpath_regex.search(line, 0) == 0 ) + { + const TQString path = line.mid(8).stripWhiteSpace(); + constr_path += path; + } + else if ( mandatory_regex.search(line, 0) == 0 ) + { + const TQString path = line.mid(18).stripWhiteSpace(); + constr_path += path; + } + else if ( manpath_map_regex.search(line, 0) == 0 ) + { + // The entry is "MANPATH_MAP " + const TQStringList mapping = + TQStringList::split(space_regex, line); + + if ( mapping.count() == 3 ) + { + const TQString dir = TQDir::cleanDirPath( mapping[1] ); + const TQString mandir = TQDir::cleanDirPath( mapping[2] ); + + manpath_map[ dir ] = mandir; + } + } + else if ( mandb_map_regex.search(line, 0) == 0 ) + { + // The entry is "MANDB_MAP " + const TQStringList mapping = + TQStringList::split(space_regex, line); + + if ( mapping.count() == 3 ) + { + const TQString mandir = TQDir::cleanDirPath( mapping[1] ); + const TQString catmandir = TQDir::cleanDirPath( mapping[2] ); + + mandb_map[ mandir ] = catmandir; + } + } + /* sections are not used + else if ( section_regex.find(line, 0) == 0 ) + { + if ( !conf_section.isEmpty() ) + conf_section += ':'; + conf_section += line.mid(8).stripWhiteSpace(); + } + */ + } + mc.close(); + } + + // Default paths + static const char *manpaths[] = { + "/usr/X11/man", + "/usr/X11R6/man", + "/usr/man", + "/usr/local/man", + "/usr/exp/man", + "/usr/openwin/man", + "/usr/dt/man", + "/opt/freetool/man", + "/opt/local/man", + "/usr/tex/man", + "/usr/www/man", + "/usr/lang/man", + "/usr/gnu/man", + "/usr/share/man", + "/usr/motif/man", + "/usr/titools/man", + "/usr/sunpc/man", + "/usr/ncd/man", + "/usr/newsprint/man", + NULL }; + + + int i = 0; + while (manpaths[i]) { + if ( constr_path.findIndex( TQString( manpaths[i] ) ) == -1 ) + constr_path += TQString( manpaths[i] ); + i++; + } + + // Directories in $PATH + // - if a manpath mapping exists, use that mapping + // - if a directory "/man" or "/../man" exists, add it + // to the man path (the actual existence check is done further down) + + if ( ::getenv("PATH") ) { + const TQStringList path = + TQStringList::split( ":", + TQString::fromLocal8Bit( ::getenv("PATH") ) ); + + for ( TQStringList::const_iterator it = path.begin(); + it != path.end(); + ++it ) + { + const TQString dir = TQDir::cleanDirPath( *it ); + TQString mandir = manpath_map[ dir ]; + + if ( !mandir.isEmpty() ) { + // a path mapping exists + if ( constr_path.findIndex( mandir ) == -1 ) + constr_path += mandir; + } + else { + // no manpath mapping, use "/man" and "/../man" + + mandir = dir + TQString( "/man" ); + if ( constr_path.findIndex( mandir ) == -1 ) + constr_path += mandir; + + int pos = dir.findRev( '/' ); + if ( pos > 0 ) { + mandir = dir.left( pos ) + TQString("/man"); + if ( constr_path.findIndex( mandir ) == -1 ) + constr_path += mandir; + } + } + TQString catmandir = mandb_map[ mandir ]; + if ( !mandir.isEmpty() ) + { + if ( constr_catmanpath.findIndex( catmandir ) == -1 ) + constr_catmanpath += catmandir; + } + else + { + // What is the default mapping? + catmandir = mandir; + catmandir.replace("/usr/share/","/var/cache/"); + if ( constr_catmanpath.findIndex( catmandir ) == -1 ) + constr_catmanpath += catmandir; + } + } + } +} + +void MANProtocol::checkManPaths() +{ + static bool inited = false; + + if (inited) + return; + + inited = true; + + const TQString manpath_env = TQString::fromLocal8Bit( ::getenv("MANPATH") ); + //TQString mansect_env = TQString::fromLocal8Bit( ::getenv("MANSECT") ); + + // Decide if $MANPATH is enough on its own or if it should be merged + // with the constructed path. + // A $MANPATH starting or ending with ":", or containing "::", + // should be merged with the constructed path. + + bool construct_path = false; + + if ( manpath_env.isEmpty() + || manpath_env[0] == ':' + || manpath_env[manpath_env.length()-1] == ':' + || manpath_env.contains( "::" ) ) + { + construct_path = true; // need to read config file + } + + // Constucted man path -- consists of paths from + // /etc/man.conf + // default dirs + // $PATH + TQStringList constr_path; + TQStringList constr_catmanpath; // catmanpath + + TQString conf_section; + + if ( construct_path ) + { + constructPath(constr_path, constr_catmanpath); + } + + m_mandbpath=constr_catmanpath; + + // Merge $MANPATH with the constructed path to form the + // actual manpath. + // + // The merging syntax with ":" and "::" in $MANPATH will be + // satisfied if any empty string in path_list_env (there + // should be 1 or 0) is replaced by the constructed path. + + const TQStringList path_list_env = TQStringList::split( ':', manpath_env , true ); + + for ( TQStringList::const_iterator it = path_list_env.begin(); + it != path_list_env.end(); + ++it ) + { + struct stat sbuf; + + TQString dir = (*it); + + if ( !dir.isEmpty() ) { + // Add dir to the man path if it exists + if ( m_manpath.findIndex( dir ) == -1 ) { + if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 + && S_ISDIR( sbuf.st_mode ) ) + { + m_manpath += dir; + } + } + } + else { + // Insert constructed path ($MANPATH was empty, or + // there was a ":" at an end or "::") + + for ( TQStringList::Iterator it2 = constr_path.begin(); + it2 != constr_path.end(); + it2++ ) + { + dir = (*it2); + + if ( !dir.isEmpty() ) { + if ( m_manpath.findIndex( dir ) == -1 ) { + if ( ::stat( TQFile::encodeName( dir ), &sbuf ) == 0 + && S_ISDIR( sbuf.st_mode ) ) + { + m_manpath += dir; + } + } + } + } + } + } + +/* sections are not used + // Sections + TQStringList m_mansect = TQStringList::split( ':', mansect_env, true ); + + const char* default_sect[] = + { "1", "2", "3", "4", "5", "6", "7", "8", "9", "n", 0L }; + + for ( int i = 0; default_sect[i] != 0L; i++ ) + if ( m_mansect.findIndex( TQString( default_sect[i] ) ) == -1 ) + m_mansect += TQString( default_sect[i] ); +*/ + +} + + +//#define _USE_OLD_CODE + +#ifdef _USE_OLD_CODE +#warning "using old code" +#else + +// Define this, if you want to compile with qsort from stdlib.h +// else the Qt Heapsort will be used. +// Note, qsort seems to be a bit faster (~10%) on a large man section +// eg. man section 3 +#define _USE_QSORT + +// Setup my own structure, with char pointers. +// from now on only pointers are copied, no strings +// +// containing the whole path string, +// the beginning of the man page name +// and the length of the name +struct man_index_t { + char *manpath; // the full path including man file + const char *manpage_begin; // pointer to the begin of the man file name in the path + int manpage_len; // len of the man file name +}; +typedef man_index_t *man_index_ptr; + +#ifdef _USE_QSORT +int compare_man_index(const void *s1, const void *s2) +{ + struct man_index_t *m1 = *(struct man_index_t **)s1; + struct man_index_t *m2 = *(struct man_index_t **)s2; + int i; + // Compare the names of the pages + // with the shorter length. + // Man page names are not '\0' terminated, so + // this is a bit tricky + if ( m1->manpage_len > m2->manpage_len) + { + i = tqstrnicmp( m1->manpage_begin, + m2->manpage_begin, + m2->manpage_len); + if (!i) + return 1; + return i; + } + + if ( m1->manpage_len < m2->manpage_len) + { + i = tqstrnicmp( m1->manpage_begin, + m2->manpage_begin, + m1->manpage_len); + if (!i) + return -1; + return i; + } + + return tqstrnicmp( m1->manpage_begin, + m2->manpage_begin, + m1->manpage_len); +} + +#else /* !_USE_QSORT */ +#warning using heapsort +// Set up my own man page list, +// with a special compare function to sort itself +typedef TQPtrList QManIndexListBase; +typedef TQPtrListIterator QManIndexListIterator; + +class QManIndexList : public QManIndexListBase +{ +public: +private: + int compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 ) + { + struct man_index_t *m1 = (struct man_index_t *)s1; + struct man_index_t *m2 = (struct man_index_t *)s2; + int i; + // compare the names of the pages + // with the shorter length + if (m1->manpage_len > m2->manpage_len) + { + i = tqstrnicmp(m1->manpage_begin, + m2->manpage_begin, + m2->manpage_len); + if (!i) + return 1; + return i; + } + + if (m1->manpage_len > m2->manpage_len) + { + + i = tqstrnicmp(m1->manpage_begin, + m2->manpage_begin, + m1->manpage_len); + if (!i) + return -1; + return i; + } + + return tqstrnicmp(m1->manpage_begin, + m2->manpage_begin, + m1->manpage_len); + } +}; + +#endif /* !_USE_QSORT */ +#endif /* !_USE_OLD_CODE */ + + + + +void MANProtocol::showIndex(const TQString& section) +{ + TQByteArray array; + TQTextStream os(array, IO_WriteOnly); + os.setEncoding(TQTextStream::UnicodeUTF8); + + // print header + os << "" << endl; + os << "" << endl; + os << "" << i18n("UNIX Manual Index") << "" << endl; + if ( !m_manCSSFile.isEmpty() ) + os << "" << endl; + os << "" << endl; + os << "
" << endl; + os << "

" << i18n( "Index for Section %1: %2").arg(section).arg(sectionName(section)) << "

" << endl; + + // compose list of search paths ------------------------------------------------------------- + + checkManPaths(); + infoMessage(i18n("Generating Index")); + + // search for the man pages + TQStringList pages = findPages( section, TQString::null ); + + TQMap indexmap = buildIndexMap(section); + + // print out the list + os << "" << endl; + +#ifdef _USE_OLD_CODE + pages.sort(); + + TQMap pagemap; + + TQStringList::ConstIterator page; + for (page = pages.begin(); page != pages.end(); ++page) + { + TQString fileName = *page; + + stripExtension( &fileName ); + + pos = fileName.findRev('/'); + if (pos > 0) + fileName = fileName.mid(pos+1); + + if (!fileName.isEmpty()) + pagemap[fileName] = *page; + + } + + for (TQMap::ConstIterator it = pagemap.begin(); + it != pagemap.end(); ++it) + { + os << "" << endl; + } + +#else /* ! _USE_OLD_CODE */ + +#ifdef _USE_QSORT + + int listlen = pages.count(); + man_index_ptr *indexlist = new man_index_ptr[listlen]; + listlen = 0; + +#else /* !_USE_QSORT */ + + QManIndexList manpages; + manpages.setAutoDelete(TRUE); + +#endif /* _USE_QSORT */ + + TQStringList::const_iterator page; + for (page = pages.begin(); page != pages.end(); ++page) + { + // I look for the beginning of the man page name + // i.e. "bla/pagename.3.gz" by looking for the last "/" + // Then look for the end of the name by searching backwards + // for the last ".", not counting zip extensions. + // If the len of the name is >0, + // store it in the list structure, to be sorted later + + char *manpage_end; + struct man_index_t *manindex = new man_index_t; + manindex->manpath = strdup((*page).utf8()); + + manindex->manpage_begin = strrchr(manindex->manpath, '/'); + if (manindex->manpage_begin) + { + manindex->manpage_begin++; + assert(manindex->manpage_begin >= manindex->manpath); + } + else + { + manindex->manpage_begin = manindex->manpath; + assert(manindex->manpage_begin >= manindex->manpath); + } + + // Skip extension ".section[.gz]" + + char *begin = (char*)(manindex->manpage_begin); + int len = strlen( begin ); + char *end = begin+(len-1); + + if ( len >= 3 && strcmp( end-2, ".gz" ) == 0 ) + end -= 3; + else if ( len >= 2 && strcmp( end-1, ".Z" ) == 0 ) + end -= 2; + else if ( len >= 2 && strcmp( end-1, ".z" ) == 0 ) + end -= 2; + else if ( len >= 4 && strcmp( end-3, ".bz2" ) == 0 ) + end -= 4; + + while ( end >= begin && *end != '.' ) + end--; + + if ( end < begin ) + manpage_end = 0; + else + manpage_end = end; + + if (NULL == manpage_end) + { + // no '.' ending ??? + // set the pointer past the end of the filename + manindex->manpage_len = (*page).length(); + manindex->manpage_len -= (manindex->manpage_begin - manindex->manpath); + assert(manindex->manpage_len >= 0); + } + else + { + manindex->manpage_len = (manpage_end - manindex->manpage_begin); + assert(manindex->manpage_len >= 0); + } + + if (0 < manindex->manpage_len) + { + +#ifdef _USE_QSORT + + indexlist[listlen] = manindex; + listlen++; + +#else /* !_USE_QSORT */ + + manpages.append(manindex); + +#endif /* _USE_QSORT */ + + } + } + + // + // Now do the sorting on the page names + // and the printout afterwards + // While printing avoid duplicate man page names + // + + struct man_index_t dummy_index = {0l,0l,0}; + struct man_index_t *last_index = &dummy_index; + +#ifdef _USE_QSORT + + // sort and print + qsort(indexlist, listlen, sizeof(struct man_index_t *), compare_man_index); + + TQChar firstchar, tmp; + TQString indexLine="
\n"; + if (indexlist[0]->manpage_len>0) + { + firstchar=TQChar((indexlist[0]->manpage_begin)[0]).lower(); + + const TQString appendixstr = TQString( + " [%3]\n" + ).arg(firstchar).arg(firstchar).arg(firstchar); + indexLine.append(appendixstr); + } + os << "
" << endl; + + for (int i=0; imanpage_begin" has not, + // so do compare at most "manindex->manpage_len" of the strings. + if (last_index->manpage_len == manindex->manpage_len && + !tqstrncmp(last_index->manpage_begin, + manindex->manpage_begin, + manindex->manpage_len) + ) + { + continue; + } + + tmp=TQChar((manindex->manpage_begin)[0]).lower(); + if (firstchar != tmp) + { + firstchar = tmp; + os << "" << endl; + + const TQString appendixstr = TQString( + " [%3]\n" + ).arg(firstchar).arg(firstchar).arg(firstchar); + indexLine.append(appendixstr); + } + os << "" << endl; + last_index = manindex; + } + indexLine.append(""); + + for (int i=0; imanpath); // allocated by strdup + delete indexlist[i]; + } + + delete [] indexlist; + +#else /* !_USE_QSORT */ + + manpages.sort(); // using + + for (QManIndexListIterator mit(manpages); + mit.current(); + ++mit ) + { + struct man_index_t *manindex = mit.current(); + + // tqstrncmp(): + // "last_man" has already a \0 string ending, but + // "manindex->manpage_begin" has not, + // so do compare at most "manindex->manpage_len" of the strings. + if (last_index->manpage_len == manindex->manpage_len && + !tqstrncmp(last_index->manpage_begin, + manindex->manpage_begin, + manindex->manpage_len) + ) + { + continue; + } + + os << "" << endl; + last_index = manindex; + } +#endif /* _USE_QSORT */ +#endif /* _USE_OLD_CODE */ + + os << "
\n" + << it.key() << "  " + << (indexmap.contains(it.key()) ? indexmap[it.key()] : "" ) + << "
\n " << firstchar <<"\n
\n " << firstchar << "\n
manpath << "\">\n"; + + ((char *)manindex->manpage_begin)[manindex->manpage_len] = '\0'; + os << manindex->manpage_begin + << "  " + << (indexmap.contains(manindex->manpage_begin) ? indexmap[manindex->manpage_begin] : "" ) + << "
manpath << "\">\n"; + + manindex->manpage_begin[manindex->manpage_len] = '\0'; + os << manindex->manpage_begin + << "  " + << (indexmap.contains(manindex->manpage_begin) ? indexmap[manindex->manpage_begin] : "" ) + << "
" << endl; + + os << indexLine << endl; + + // print footer + os << "" << endl; + + infoMessage(TQString::null); + mimeType("text/html"); + data(array); + finished(); +} + +void MANProtocol::listDir(const KURL &url) +{ + kdDebug( 7107 ) << "ENTER listDir: " << url.prettyURL() << endl; + + TQString title; + TQString section; + + if ( !parseUrl(url.path(), title, section) ) { + error( TDEIO::ERR_MALFORMED_URL, url.url() ); + return; + } + + TQStringList list = findPages( section, TQString::null, false ); + + UDSEntryList uds_entry_list; + UDSEntry uds_entry; + UDSAtom uds_atom; + + uds_atom.m_uds = TDEIO::UDS_NAME; // we only do names... + uds_entry.append( uds_atom ); + + TQStringList::Iterator it = list.begin(); + TQStringList::Iterator end = list.end(); + + for ( ; it != end; ++it ) { + stripExtension( &(*it) ); + + uds_entry[0].m_str = *it; + uds_entry_list.append( uds_entry ); + } + + listEntries( uds_entry_list ); + finished(); +} + +void MANProtocol::getProgramPath() +{ + if (!mySgml2RoffPath.isEmpty()) + return; + + mySgml2RoffPath = TDEGlobal::dirs()->findExe("sgml2roff"); + if (!mySgml2RoffPath.isEmpty()) + return; + + /* sgml2roff isn't found in PATH. Check some possible locations where it may be found. */ + mySgml2RoffPath = TDEGlobal::dirs()->findExe("sgml2roff", TQString(SGML2ROFF_DIRS)); + if (!mySgml2RoffPath.isEmpty()) + return; + + /* Cannot find sgml2roff programm: */ + outputError(i18n("Could not find the sgml2roff program on your system. Please install it, if necessary, and extend the search path by adjusting the environment variable PATH before starting TDE.")); + finished(); + exit(); +} diff --git a/tdeioslave/man/tdeio_man.css b/tdeioslave/man/tdeio_man.css new file mode 100644 index 000000000..8a9f378bc --- /dev/null +++ b/tdeioslave/man/tdeio_man.css @@ -0,0 +1,21 @@ +body {background-color:#fffff} + +/*for the list of one manpage section*/ +.secidxshort { + display:block; + position:absolute;overflow:auto; + top:0px;bottom:95%;left:0;right:0; +} +.secidxmain { +/*misfortunately accessing anchors in a scrollview + doesn't seem to work yet with konqi, so:*/ +/* + position:absolute;overflow:auto; + top:5%;bottom:0;left:0;right:0; +*/ +} +.secidxnextletter { + font-size:larger; + border-bottom:1px solid black; + text-align:center +} diff --git a/tdeioslave/man/tdeio_man.h b/tdeioslave/man/tdeio_man.h new file mode 100644 index 000000000..7ba9d1dbc --- /dev/null +++ b/tdeioslave/man/tdeio_man.h @@ -0,0 +1,100 @@ +/* This file is part of the KDE libraries + Copyright (c) 2000 Matthias Hoelzer-Kluepfel + + + 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 __tdeio_man_h__ +#define __tdeio_man_h__ + + +#include +#include +#include +#include +#include + + +#include +#include + + +class MANProtocol : public TQObject, public TDEIO::SlaveBase +{ + Q_OBJECT + +public: + + MANProtocol(const TQCString &pool_socket, const TQCString &app_socket); + virtual ~MANProtocol(); + + virtual void get(const KURL& url); + virtual void stat(const KURL& url); + + virtual void mimetype(const KURL &url); + virtual void listDir(const KURL &url); + + void outputError(const TQString& errmsg); + void outputMatchingPages(const TQStringList &matchingPages); + + void showMainIndex(); + void showIndex(const TQString& section); + + // the following two functions are the interface to man2html + void output(const char *insert); + char *readManPage(const char *filename); + + static MANProtocol *self(); + +private slots: + void slotGetStdOutput(TDEProcess*, char*, int); + void slotGetStdOutputUtf8(TDEProcess*, char*, int); + +private: + void checkManPaths(); + TQStringList manDirectories(); + TQMap buildIndexMap(const TQString& section); + bool addWhatIs(TQMap& i, const TQString& f, const TQString& mark); + void parseWhatIs( TQMap &i, TQTextStream &t, const TQString &mark ); + TQStringList findPages(const TQString& section, + const TQString &title, + bool full_path = true); + + void addToBuffer(const char *buffer, int buflen); + TQString pageName(const TQString& page) const; + TQStringList buildSectionList(const TQStringList& dirs) const; + void constructPath(TQStringList& constr_path, TQStringList constr_catmanpath); +private: + static MANProtocol *_self; + TQCString lastdir; + + void findManPagesInSection(const TQString &dir, const TQString &title, bool full_path, TQStringList &list); + TQStringList m_manpath; ///< Path of man directories + TQStringList m_mandbpath; ///< Path of catman directories + TQStringList section_names; + + TQString myStdStream; + TQString mySgml2RoffPath; + void getProgramPath(); + + TQCString m_htmlPath; ///< Path to TDE resources, encoded for HTML + TQCString m_cssPath; ///< Path to TDE resources, encoded for CSS + TQBuffer m_outputBuffer; ///< Buffer for the output + TQString m_manCSSFile; ///< Path to tdeio_man.css +}; + + +#endif diff --git a/tdeioslave/man/tdeio_man_test.cpp b/tdeioslave/man/tdeio_man_test.cpp new file mode 100644 index 000000000..a7f41434e --- /dev/null +++ b/tdeioslave/man/tdeio_man_test.cpp @@ -0,0 +1,38 @@ + + +#include + +#include "tdeio_man.h" + + +#include +#include + + +class tdeio_man_test : public MANProtocol +{ + Q_OBJECT + +public: + tdeio_man_test(const TQCString &pool_socket, const TQCString &app_socket); + +protected: + virtual void data(int); + +}; + + + + + +int main(int argc, char **argv) +{ + TDEApplication a( argc, argv , "p2"); + + MANProtocol testproto("/tmp/tdeiotest.in", "/tmp/tdeiotest.out"); + testproto.showIndex("3"); + + return 0; +} + + diff --git a/tdeioslave/media/CMakeLists.txt b/tdeioslave/media/CMakeLists.txt index 68d4bf9d6..0746d259c 100644 --- a/tdeioslave/media/CMakeLists.txt +++ b/tdeioslave/media/CMakeLists.txt @@ -38,22 +38,22 @@ link_directories( install( FILES media.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kiomedia (static) ######################### +##### tdeiomedia (static) ######################### -set( target kiomedia ) +set( target tdeiomedia ) tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES kio_media.cpp mediaimpl.cpp mediaimpl.skel + SOURCES tdeio_media.cpp mediaimpl.cpp mediaimpl.skel ) -##### kio_media (module) ######################## +##### tdeio_media (module) ######################## -set( target kio_media ) +set( target tdeio_media ) tde_add_kpart( ${target} AUTOMOC SOURCES dummy.cpp - EMBED kiomedia-static + EMBED tdeiomedia-static LINK mediacommon-static tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/media/Makefile.am b/tdeioslave/media/Makefile.am index b82e48557..c827568a4 100644 --- a/tdeioslave/media/Makefile.am +++ b/tdeioslave/media/Makefile.am @@ -8,11 +8,11 @@ SUBDIRS = libmediacommon . mediamanager medianotifier mounthelper \ INCLUDES = -I$(srcdir)/libmediacommon $(all_includes) METASOURCES = AUTO -kde_module_LTLIBRARIES = kio_media.la +kde_module_LTLIBRARIES = tdeio_media.la -kio_media_la_SOURCES = dummy.cpp -kio_media_la_LIBADD = libtdeiomedia.la libmediacommon/libmediacommon.la $(LIB_KIO) -kio_media_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined +tdeio_media_la_SOURCES = dummy.cpp +tdeio_media_la_LIBADD = libtdeiomedia.la libmediacommon/libmediacommon.la $(LIB_KIO) +tdeio_media_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined dummy.cpp: echo > dummy.cpp @@ -20,7 +20,7 @@ dummy.cpp: kde_services_DATA = media.protocol noinst_LTLIBRARIES = libtdeiomedia.la -libtdeiomedia_la_SOURCES = kio_media.cpp mediaimpl.cpp mediaimpl.skel +libtdeiomedia_la_SOURCES = tdeio_media.cpp mediaimpl.cpp mediaimpl.skel check_PROGRAMS = testmedia testmedia_SOURCES = testmedia.cpp diff --git a/tdeioslave/media/kio_media.cpp b/tdeioslave/media/kio_media.cpp deleted file mode 100644 index d1647c6fc..000000000 --- a/tdeioslave/media/kio_media.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include -#include -#include -#include - -#include - -#include "mediaimpl.h" -#include "kio_media.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 ) - { - // TDEApplication is necessary to use other ioslaves - putenv(strdup("SESSION_MANAGER=")); - TDECmdLineArgs::init(argc, argv, "kio_media", 0, 0, 0, 0); - TDECmdLineArgs::addCmdLineOptions( options ); - TDEApplication app( false, false ); - // We want to be anonymous even if we use DCOP - app.dcopClient()->attach(); - - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - MediaProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); - slave.dispatchLoop(); - return 0; - } -} - - -MediaProtocol::MediaProtocol(const TQCString &protocol, - const TQCString &pool, const TQCString &app) - : ForwardingSlaveBase(protocol, pool, app) -{ - connect( &m_impl, TQT_SIGNAL( warning( const TQString & ) ), - this, TQT_SLOT( slotWarning( const TQString & ) ) ); -} - -MediaProtocol::~MediaProtocol() -{ -} - -bool MediaProtocol::rewriteURL(const KURL &url, KURL &newUrl) -{ - TQString name, path; - - if ( !m_impl.parseURL(url, name, path) ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return false; - } - - - if ( !m_impl.realURL(name, path, newUrl) ) - { - error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); - return false; - } - - return true; -} - -void MediaProtocol::put(const KURL &url, int permissions, - bool overwrite, bool resume) -{ - kdDebug(1219) << "MediaProtocol::put: " << url << endl; - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( ok && path.isEmpty() ) - { - error(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, url.prettyURL()); - } - else - { - ForwardingSlaveBase::put(url, permissions, overwrite, resume); - } -} - -void MediaProtocol::rename(const KURL &src, const KURL &dest, bool overwrite) -{ - kdDebug(1219) << "MediaProtocol::rename: " << src << ", " << dest << ", " - << overwrite << endl; - - TQString src_name, src_path; - bool ok = m_impl.parseURL(src, src_name, src_path); - TQString dest_name, dest_path; - ok &= m_impl.parseURL(dest, dest_name, dest_path); - - if ( ok && src_path.isEmpty() && dest_path.isEmpty() - && src.protocol() == "media" && dest.protocol() == "media" ) - { - if (!m_impl.setUserLabel(src_name, dest_name)) - { - error(m_impl.lastErrorCode(), m_impl.lastErrorMessage()); - } - else - { - finished(); - } - } - else - { - ForwardingSlaveBase::rename(src, dest, overwrite); - } -} - -void MediaProtocol::mkdir(const KURL &url, int permissions) -{ - kdDebug(1219) << "MediaProtocol::mkdir: " << url << endl; - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( ok && path.isEmpty() ) - { - error(TDEIO::ERR_COULD_NOT_MKDIR, url.prettyURL()); - } - else - { - ForwardingSlaveBase::mkdir(url, permissions); - } -} - -void MediaProtocol::del(const KURL &url, bool isFile) -{ - kdDebug(1219) << "MediaProtocol::del: " << url << endl; - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( ok && path.isEmpty() ) - { - error(TDEIO::ERR_CANNOT_DELETE, url.prettyURL()); - } - else - { - ForwardingSlaveBase::del(url, isFile); - } -} - -void MediaProtocol::stat(const KURL &url) -{ - kdDebug(1219) << "MediaProtocol::stat: " << url << endl; - TQString path = url.path(); - if( path.isEmpty() || path == "/" ) - { - // The root is "virtual" - it's not a single physical directory - TDEIO::UDSEntry entry; - m_impl.createTopLevelEntry( entry ); - statEntry( entry ); - finished(); - return; - } - - TQString name; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - if( path.isEmpty() ) - { - TDEIO::UDSEntry entry; - - if ( m_impl.statMedium(name, entry) - || m_impl.statMediumByLabel(name, entry) ) - { - statEntry(entry); - finished(); - } - else - { - error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - } - } - else - { - ForwardingSlaveBase::stat(url); - } -} - -void MediaProtocol::listDir(const KURL &url) -{ - kdDebug(1219) << "MediaProtocol::listDir: " << url << endl; - - if ( url.path().length() <= 1 ) - { - listRoot(); - return; - } - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - ForwardingSlaveBase::listDir(url); -} - -void MediaProtocol::listRoot() -{ - TDEIO::UDSEntry entry; - - TDEIO::UDSEntryList media_entries; - bool ok = m_impl.listMedia(media_entries); - - if (!ok) - { - error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); - return; - } - - totalSize(media_entries.count()+1); - - m_impl.createTopLevelEntry(entry); - listEntry(entry, false); - - TDEIO::UDSEntryListIterator it = media_entries.begin(); - TDEIO::UDSEntryListIterator end = media_entries.end(); - - for(; it!=end; ++it) - { - listEntry(*it, false); - } - - entry.clear(); - listEntry(entry, true); - - finished(); -} - -void MediaProtocol::slotWarning( const TQString &msg ) -{ - warning( msg ); -} - -#include "kio_media.moc" diff --git a/tdeioslave/media/kio_media.h b/tdeioslave/media/kio_media.h deleted file mode 100644 index bf1325475..000000000 --- a/tdeioslave/media/kio_media.h +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _KIO_MEDIA_H_ -#define _KIO_MEDIA_H_ - -#include - -#include "mediaimpl.h" - -class MediaProtocol : public TDEIO::ForwardingSlaveBase -{ -Q_OBJECT -public: - MediaProtocol(const TQCString &protocol, const TQCString &pool, - const TQCString &app); - virtual ~MediaProtocol(); - - virtual bool rewriteURL(const KURL &url, KURL &newUrl); - - virtual void put(const KURL &url, int permissions, - bool overwrite, bool resume); - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - virtual void mkdir(const KURL &url, int permissions); - virtual void del(const KURL &url, bool isFile); - virtual void stat(const KURL &url); - virtual void listDir(const KURL &url); - -private slots: - void slotWarning( const TQString &msg ); - -private: - void listRoot(); - - MediaImpl m_impl; -}; - -#endif diff --git a/tdeioslave/media/media.protocol b/tdeioslave/media/media.protocol index f535e1a41..c390d6fca 100644 --- a/tdeioslave/media/media.protocol +++ b/tdeioslave/media/media.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_media +exec=tdeio_media protocol=media input=none output=filesystem diff --git a/tdeioslave/media/mediamanager/halbackend.cpp b/tdeioslave/media/mediamanager/halbackend.cpp index aba2b0175..1022b36be 100644 --- a/tdeioslave/media/mediamanager/halbackend.cpp +++ b/tdeioslave/media/mediamanager/halbackend.cpp @@ -377,7 +377,7 @@ void HALBackend::DeviceCondition(const char* udi, const char* condition) } if (medium) { TDEProcess p; - p << "kio_media_mounthelper" << "-e" << medium->name(); + p << "tdeio_media_mounthelper" << "-e" << medium->name(); p.start(TDEProcess::DontCare); } } diff --git a/tdeioslave/media/mediamanager/mediamanager.cpp b/tdeioslave/media/mediamanager/mediamanager.cpp index db2c12a71..511eb6c64 100644 --- a/tdeioslave/media/mediamanager/mediamanager.cpp +++ b/tdeioslave/media/mediamanager/mediamanager.cpp @@ -415,7 +415,7 @@ void MediaManager::slotMediumChanged(const TQString &/*id*/, const TQString &nam extern "C" { KDE_EXPORT KDEDModule *create_mediamanager(const TQCString &obj) { - TDEGlobal::locale()->insertCatalogue("kio_media"); + TDEGlobal::locale()->insertCatalogue("tdeio_media"); return new MediaManager(obj); } } diff --git a/tdeioslave/media/mounthelper/CMakeLists.txt b/tdeioslave/media/mounthelper/CMakeLists.txt index ea06278a8..766fe3def 100644 --- a/tdeioslave/media/mounthelper/CMakeLists.txt +++ b/tdeioslave/media/mounthelper/CMakeLists.txt @@ -21,12 +21,12 @@ link_directories( ) -##### kio_media_mounthelper (executable) ######## +##### tdeio_media_mounthelper (executable) ######## -set( target kio_media_mounthelper ) +set( target tdeio_media_mounthelper ) set( ${target}_SRCS - kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp + tdeio_media_mounthelper.cpp decryptdialog.ui dialog.cpp ) tde_add_executable( ${target} AUTOMOC diff --git a/tdeioslave/media/mounthelper/Makefile.am b/tdeioslave/media/mounthelper/Makefile.am index 934559d40..c1e056c18 100644 --- a/tdeioslave/media/mounthelper/Makefile.am +++ b/tdeioslave/media/mounthelper/Makefile.am @@ -1,12 +1,12 @@ -bin_PROGRAMS = kio_media_mounthelper +bin_PROGRAMS = tdeio_media_mounthelper INCLUDES = -I$(srcdir)/../libmediacommon $(all_includes) AM_LDFLAGS = $(all_libraries) -kio_media_mounthelper_SOURCES = kio_media_mounthelper.cpp decryptdialog.ui dialog.cpp +tdeio_media_mounthelper_SOURCES = tdeio_media_mounthelper.cpp decryptdialog.ui dialog.cpp -kio_media_mounthelper_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -kio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) $(LIB_TDEUI) +tdeio_media_mounthelper_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +tdeio_media_mounthelper_LDADD = ../libmediacommon/libmediacommon.la $(LIB_KIO) $(LIB_TDEUI) METASOURCES = AUTO diff --git a/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp b/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp deleted file mode 100644 index f321293d6..000000000 --- a/tdeioslave/media/mounthelper/kio_media_mounthelper.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kévin Ottens - Parts of this file are - Copyright 2003 Waldo Bastian - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialog.h" -#include "kio_media_mounthelper.h" - -const Medium MountHelper::findMedium(const KURL &url) -{ - DCOPRef mediamanager("kded", "mediamanager"); - - // Try filename first - DCOPReply reply = mediamanager.call( "properties", url.fileName() ); - if ( !reply.isValid() ) { - m_errorStr = i18n("The TDE mediamanager is not running.")+"\n"; - return Medium(TQString::null, TQString::null, TQString::null); - } - const Medium& medium = Medium::create(reply); - if ( medium.id().isEmpty() ) { - // Try full URL now - reply = mediamanager.call( "properties", url.prettyURL() ); - if ( !reply.isValid() ) { - m_errorStr = i18n("Internal Error"); - return Medium(TQString::null, TQString::null, TQString::null); - } - return Medium::create(reply); - } else { - return medium; - } -} - -MountHelper::MountHelper() : TDEApplication() -{ - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - - m_errorStr = TQString::null; - - KURL url(args->url(0)); - const Medium medium = findMedium(url); - - if ( medium.id().isEmpty() ) - { - if (m_errorStr.isEmpty()) - m_errorStr+= i18n("%1 cannot be found.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; - } - - if ( !medium.isMountable() && !args->isSet("e") && !args->isSet("s")) - { - m_errorStr = i18n("%1 is not a mountable media.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; - } - - TQString device = medium.deviceNode(); - TQString mount_point = medium.mountPoint(); - - m_isCdrom = medium.mimeType().find("dvd")!=-1 - || medium.mimeType().find("cd")!=-1; - - if (args->isSet("d")) - { - if (!medium.isEncrypted()) - { - m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; - } - if (!medium.needDecryption()) - { - m_errorStr = i18n("%1 is already decrypted.").arg(url.prettyURL()); - TQTimer::singleShot(0, this, TQT_SLOT(error()) ); - return; - } - - TQString iconName = medium.iconName(); - if (iconName.isEmpty()) - { - TQString mime = medium.mimeType(); - iconName = KMimeType::mimeType(mime)->icon(mime, false); - } - - m_mediumId = medium.id(); - dialog = new Dialog(url.prettyURL(), iconName); - dialog->show(); - - connect(dialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotSendPassword())); - connect(dialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotCancel())); - connect(this, TQT_SIGNAL (signalPasswordError(TQString)), dialog, TQT_SLOT (slotDialogError(TQString))); - } - else if (args->isSet("u")) - { - DCOPRef mediamanager("kded", "mediamanager"); - DCOPReply reply = mediamanager.call( "unmount", medium.id()); - if (reply.isValid()) - reply.get(m_errorStr); - kdDebug() << "medium unmount " << m_errorStr << endl; - if (m_errorStr.isNull()) - ::exit(0); - else - error(); - } - else if (args->isSet("s") || args->isSet("e")) - { - DCOPRef mediamanager("kded", "mediamanager"); - - /* - * We want to call mediamanager unmount before invoking eject. That's - * because unmount would provide an informative error message in case of - * failure. However, there are cases when unmount would fail - * (supermount, slackware, see bug#116209) but eject would succeed. - * Thus if unmount fails, save unmount error message and invokeEject() - * anyway. Only if both unmount and eject fail, notify the user by - * displaying the saved error message (see ejectFinished()). - */ - if (medium.isMounted()) - { - DCOPReply reply = mediamanager.call( "unmount", medium.id()); - if (reply.isValid()) - reply.get(m_errorStr); - } - - /* If this is a decrypted volume and there is no error yet - * we try to teardown the decryption */ - if (m_errorStr.isNull() && medium.isEncrypted() && !medium.clearDeviceUdi().isNull()) - { - DCOPReply reply = mediamanager.call( "undecrypt", medium.id()); - if (reply.isValid()) - reply.get(m_errorStr); - } - - if (m_errorStr.isNull()) - invokeEject(device, true); - else - error(); - } - else - { - DCOPRef mediamanager("kded", "mediamanager"); - DCOPReply reply = mediamanager.call( "mount", medium.id()); - if (reply.isValid()) - reply.get(m_errorStr); - if (m_errorStr.isNull()) - ::exit(0); - else - error(); - } -} - -void MountHelper::invokeEject(const TQString &device, bool quiet) -{ - TDEProcess *proc = new TDEProcess(TQT_TQOBJECT(this)); - *proc << "kdeeject"; - if (quiet) - { - *proc << "-q"; - } - *proc << device; - connect( proc, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT( ejectFinished(TDEProcess *) ) ); - proc->start(); -} - -void MountHelper::ejectFinished(TDEProcess* proc) -{ - /* - * If eject failed, report the error stored in m_errorStr - */ - if (proc->normalExit() && proc->exitStatus() == 0) { - ::exit(0); - } else { - if (m_errorStr.isEmpty()) { - if (m_isCdrom) - m_errorStr = i18n("The device was successfully unmounted, but the tray could not be opened"); - else - m_errorStr = i18n("The device was successfully unmounted, but could not be ejected"); - } -//X Comment this because the error is useless as long as the unmount is successful. -//X TQTimer::singleShot(0, this, TQT_SLOT(error())); - ::exit(0); - } -} - -void MountHelper::error() -{ - TQString prettyErrorString = m_errorStr; - if (m_errorStr.contains("<") && m_errorStr.contains(">")) { - if (!m_errorStr.contains("")) { - prettyErrorString = TQString("%1").arg(m_errorStr); - } - } - KMessageBox::error(0, prettyErrorString); - ::exit(1); -} - -void MountHelper::slotSendPassword() -{ - DCOPRef mediamanager("kded", "mediamanager"); - - DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() ); - if (!reply.isValid()) { - m_errorStr = i18n("The TDE mediamanager is not running."); - error(); - } else { - TQString errorMsg = reply; - if (errorMsg.isNull()) { - exit(0); - } else { - emit signalPasswordError(errorMsg); - } - } -} - -void MountHelper::slotCancel() -{ - exit(0); -} - -static KCmdLineOptions options[] = -{ - { "d", I18N_NOOP("Decrypt given URL"), 0 }, - { "u", I18N_NOOP("Unmount given URL"), 0 }, - { "m", I18N_NOOP("Mount given URL (default)"), 0 }, - { "e", I18N_NOOP("Eject given URL via kdeeject"), 0}, - { "s", I18N_NOOP("Unmount and Eject given URL (necessary for some USB devices)"), 0}, - {"!+URL", I18N_NOOP("media:/ URL to mount/unmount/eject/remove"), 0 }, - KCmdLineLastOption -}; - - -int main(int argc, char **argv) -{ - TDECmdLineArgs::init(argc, argv, "kio_media_mounthelper", - "kio_media_mounthelper", "kio_media_mounthelper", - "0.1"); - - TDECmdLineArgs::addCmdLineOptions( options ); - TDEGlobal::locale()->setMainCatalogue("kio_media"); - TDEApplication::addCmdLineOptions(); - - if (TDECmdLineArgs::parsedArgs()->count()==0) TDECmdLineArgs::usage(); - TDEApplication *app = new MountHelper(); - - KStartupInfo::appStarted(); - app->dcopClient()->attach(); - return app->exec(); -} - -#include "kio_media_mounthelper.moc" diff --git a/tdeioslave/media/mounthelper/kio_media_mounthelper.h b/tdeioslave/media/mounthelper/kio_media_mounthelper.h deleted file mode 100644 index 50ea88b3b..000000000 --- a/tdeioslave/media/mounthelper/kio_media_mounthelper.h +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kévin Ottens - Parts of this file are - Copyright 2003 Waldo Bastian - - 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_MEDIA_MOUNTHELPER_H_ -#define _KIO_MEDIA_MOUNTHELPER_H_ - -#include -#include -#include - -#include "medium.h" - -class Dialog; - -class MountHelper : public TDEApplication -{ - Q_OBJECT -public: - MountHelper(); - -private: - const Medium findMedium(const KURL &url); - void invokeEject(const TQString &device, bool quiet=false); - TQString m_errorStr; - bool m_isCdrom; - TQString m_mediumId; - Dialog *dialog; - -private slots: - void slotSendPassword(); - void slotCancel(); - void ejectFinished(TDEProcess* proc); - void error(); - -signals: - void signalPasswordError(TQString errorMsg); -}; - -#endif diff --git a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp new file mode 100644 index 000000000..038a4de57 --- /dev/null +++ b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.cpp @@ -0,0 +1,282 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kévin Ottens + Parts of this file are + Copyright 2003 Waldo Bastian + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog.h" +#include "tdeio_media_mounthelper.h" + +const Medium MountHelper::findMedium(const KURL &url) +{ + DCOPRef mediamanager("kded", "mediamanager"); + + // Try filename first + DCOPReply reply = mediamanager.call( "properties", url.fileName() ); + if ( !reply.isValid() ) { + m_errorStr = i18n("The TDE mediamanager is not running.")+"\n"; + return Medium(TQString::null, TQString::null, TQString::null); + } + const Medium& medium = Medium::create(reply); + if ( medium.id().isEmpty() ) { + // Try full URL now + reply = mediamanager.call( "properties", url.prettyURL() ); + if ( !reply.isValid() ) { + m_errorStr = i18n("Internal Error"); + return Medium(TQString::null, TQString::null, TQString::null); + } + return Medium::create(reply); + } else { + return medium; + } +} + +MountHelper::MountHelper() : TDEApplication() +{ + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + m_errorStr = TQString::null; + + KURL url(args->url(0)); + const Medium medium = findMedium(url); + + if ( medium.id().isEmpty() ) + { + if (m_errorStr.isEmpty()) + m_errorStr+= i18n("%1 cannot be found.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + if ( !medium.isMountable() && !args->isSet("e") && !args->isSet("s")) + { + m_errorStr = i18n("%1 is not a mountable media.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + TQString device = medium.deviceNode(); + TQString mount_point = medium.mountPoint(); + + m_isCdrom = medium.mimeType().find("dvd")!=-1 + || medium.mimeType().find("cd")!=-1; + + if (args->isSet("d")) + { + if (!medium.isEncrypted()) + { + m_errorStr = i18n("%1 is not an encrypted media.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + if (!medium.needDecryption()) + { + m_errorStr = i18n("%1 is already decrypted.").arg(url.prettyURL()); + TQTimer::singleShot(0, this, TQT_SLOT(error()) ); + return; + } + + TQString iconName = medium.iconName(); + if (iconName.isEmpty()) + { + TQString mime = medium.mimeType(); + iconName = KMimeType::mimeType(mime)->icon(mime, false); + } + + m_mediumId = medium.id(); + dialog = new Dialog(url.prettyURL(), iconName); + dialog->show(); + + connect(dialog, TQT_SIGNAL (user1Clicked()), this, TQT_SLOT (slotSendPassword())); + connect(dialog, TQT_SIGNAL (cancelClicked()), this, TQT_SLOT (slotCancel())); + connect(this, TQT_SIGNAL (signalPasswordError(TQString)), dialog, TQT_SLOT (slotDialogError(TQString))); + } + else if (args->isSet("u")) + { + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "unmount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + kdDebug() << "medium unmount " << m_errorStr << endl; + if (m_errorStr.isNull()) + ::exit(0); + else + error(); + } + else if (args->isSet("s") || args->isSet("e")) + { + DCOPRef mediamanager("kded", "mediamanager"); + + /* + * We want to call mediamanager unmount before invoking eject. That's + * because unmount would provide an informative error message in case of + * failure. However, there are cases when unmount would fail + * (supermount, slackware, see bug#116209) but eject would succeed. + * Thus if unmount fails, save unmount error message and invokeEject() + * anyway. Only if both unmount and eject fail, notify the user by + * displaying the saved error message (see ejectFinished()). + */ + if (medium.isMounted()) + { + DCOPReply reply = mediamanager.call( "unmount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + } + + /* If this is a decrypted volume and there is no error yet + * we try to teardown the decryption */ + if (m_errorStr.isNull() && medium.isEncrypted() && !medium.clearDeviceUdi().isNull()) + { + DCOPReply reply = mediamanager.call( "undecrypt", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + } + + if (m_errorStr.isNull()) + invokeEject(device, true); + else + error(); + } + else + { + DCOPRef mediamanager("kded", "mediamanager"); + DCOPReply reply = mediamanager.call( "mount", medium.id()); + if (reply.isValid()) + reply.get(m_errorStr); + if (m_errorStr.isNull()) + ::exit(0); + else + error(); + } +} + +void MountHelper::invokeEject(const TQString &device, bool quiet) +{ + TDEProcess *proc = new TDEProcess(TQT_TQOBJECT(this)); + *proc << "kdeeject"; + if (quiet) + { + *proc << "-q"; + } + *proc << device; + connect( proc, TQT_SIGNAL(processExited(TDEProcess *)), + this, TQT_SLOT( ejectFinished(TDEProcess *) ) ); + proc->start(); +} + +void MountHelper::ejectFinished(TDEProcess* proc) +{ + /* + * If eject failed, report the error stored in m_errorStr + */ + if (proc->normalExit() && proc->exitStatus() == 0) { + ::exit(0); + } else { + if (m_errorStr.isEmpty()) { + if (m_isCdrom) + m_errorStr = i18n("The device was successfully unmounted, but the tray could not be opened"); + else + m_errorStr = i18n("The device was successfully unmounted, but could not be ejected"); + } +//X Comment this because the error is useless as long as the unmount is successful. +//X TQTimer::singleShot(0, this, TQT_SLOT(error())); + ::exit(0); + } +} + +void MountHelper::error() +{ + TQString prettyErrorString = m_errorStr; + if (m_errorStr.contains("<") && m_errorStr.contains(">")) { + if (!m_errorStr.contains("")) { + prettyErrorString = TQString("%1").arg(m_errorStr); + } + } + KMessageBox::error(0, prettyErrorString); + ::exit(1); +} + +void MountHelper::slotSendPassword() +{ + DCOPRef mediamanager("kded", "mediamanager"); + + DCOPReply reply = mediamanager.call( "decrypt", m_mediumId, dialog->getPassword() ); + if (!reply.isValid()) { + m_errorStr = i18n("The TDE mediamanager is not running."); + error(); + } else { + TQString errorMsg = reply; + if (errorMsg.isNull()) { + exit(0); + } else { + emit signalPasswordError(errorMsg); + } + } +} + +void MountHelper::slotCancel() +{ + exit(0); +} + +static KCmdLineOptions options[] = +{ + { "d", I18N_NOOP("Decrypt given URL"), 0 }, + { "u", I18N_NOOP("Unmount given URL"), 0 }, + { "m", I18N_NOOP("Mount given URL (default)"), 0 }, + { "e", I18N_NOOP("Eject given URL via kdeeject"), 0}, + { "s", I18N_NOOP("Unmount and Eject given URL (necessary for some USB devices)"), 0}, + {"!+URL", I18N_NOOP("media:/ URL to mount/unmount/eject/remove"), 0 }, + KCmdLineLastOption +}; + + +int main(int argc, char **argv) +{ + TDECmdLineArgs::init(argc, argv, "tdeio_media_mounthelper", + "tdeio_media_mounthelper", "tdeio_media_mounthelper", + "0.1"); + + TDECmdLineArgs::addCmdLineOptions( options ); + TDEGlobal::locale()->setMainCatalogue("tdeio_media"); + TDEApplication::addCmdLineOptions(); + + if (TDECmdLineArgs::parsedArgs()->count()==0) TDECmdLineArgs::usage(); + TDEApplication *app = new MountHelper(); + + KStartupInfo::appStarted(); + app->dcopClient()->attach(); + return app->exec(); +} + +#include "tdeio_media_mounthelper.moc" diff --git a/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h new file mode 100644 index 000000000..50ea88b3b --- /dev/null +++ b/tdeioslave/media/mounthelper/tdeio_media_mounthelper.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kévin Ottens + Parts of this file are + Copyright 2003 Waldo Bastian + + 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_MEDIA_MOUNTHELPER_H_ +#define _KIO_MEDIA_MOUNTHELPER_H_ + +#include +#include +#include + +#include "medium.h" + +class Dialog; + +class MountHelper : public TDEApplication +{ + Q_OBJECT +public: + MountHelper(); + +private: + const Medium findMedium(const KURL &url); + void invokeEject(const TQString &device, bool quiet=false); + TQString m_errorStr; + bool m_isCdrom; + TQString m_mediumId; + Dialog *dialog; + +private slots: + void slotSendPassword(); + void slotCancel(); + void ejectFinished(TDEProcess* proc); + void error(); + +signals: + void signalPasswordError(TQString errorMsg); +}; + +#endif diff --git a/tdeioslave/media/services/media_decrypt.desktop b/tdeioslave/media/services/media_decrypt.desktop index dd8dadc39..4adef7d90 100644 --- a/tdeioslave/media/services/media_decrypt.desktop +++ b/tdeioslave/media/services/media_decrypt.desktop @@ -1,5 +1,5 @@ [Desktop Action Decrypt] -Exec=kio_media_mounthelper -d %u +Exec=tdeio_media_mounthelper -d %u Icon=decrypted Name=Decrypt Name[de]=Entschlüsseln diff --git a/tdeioslave/media/services/media_eject.desktop b/tdeioslave/media/services/media_eject.desktop index af30d1088..121f83340 100644 --- a/tdeioslave/media/services/media_eject.desktop +++ b/tdeioslave/media/services/media_eject.desktop @@ -86,5 +86,5 @@ Name[xh]=Khuphela ngaphandle Name[zh_CN]=弹出 Name[zh_TW]=退出 Name[zu]=Khipha -Exec=kio_media_mounthelper -e %u +Exec=tdeio_media_mounthelper -e %u diff --git a/tdeioslave/media/services/media_mount.desktop b/tdeioslave/media/services/media_mount.desktop index 8011fe577..a8a943bb8 100644 --- a/tdeioslave/media/services/media_mount.desktop +++ b/tdeioslave/media/services/media_mount.desktop @@ -83,5 +83,5 @@ Name[xh]=Layisha Name[zh_CN]=挂载 Name[zh_TW]=掛載 Name[zu]=Yenyusa -Exec=kio_media_mounthelper -m %u +Exec=tdeio_media_mounthelper -m %u diff --git a/tdeioslave/media/services/media_safelyremove.desktop b/tdeioslave/media/services/media_safelyremove.desktop index 3dac85f15..37f3d3b7b 100644 --- a/tdeioslave/media/services/media_safelyremove.desktop +++ b/tdeioslave/media/services/media_safelyremove.desktop @@ -71,5 +71,5 @@ Name[vi]=Gỡ ra An toàn Name[wa]=Ositer e sÃ¥vrité Name[zh_CN]=安全删除 Name[zh_TW]=安全的移除 -Exec=kio_media_mounthelper -s %u +Exec=tdeio_media_mounthelper -s %u diff --git a/tdeioslave/media/services/media_unmount.desktop b/tdeioslave/media/services/media_unmount.desktop index 04ced9d0d..c76adf1f5 100644 --- a/tdeioslave/media/services/media_unmount.desktop +++ b/tdeioslave/media/services/media_unmount.desktop @@ -83,5 +83,5 @@ Name[xh]=Sukuyilayisha Name[zh_CN]=å¸è½½ Name[zh_TW]=å¸è¼‰ Name[zu]=Yehlisa -Exec=kio_media_mounthelper -u %u +Exec=tdeio_media_mounthelper -u %u diff --git a/tdeioslave/media/tdecmodule/main.cpp b/tdeioslave/media/tdecmodule/main.cpp index 9036583df..9d8c4cb8f 100644 --- a/tdeioslave/media/tdecmodule/main.cpp +++ b/tdeioslave/media/tdecmodule/main.cpp @@ -39,7 +39,7 @@ K_EXPORT_COMPONENT_FACTORY( kcm_media, MediaFactory( "kcmmedia" ) ) MediaModule::MediaModule( TQWidget *parent, const char *name, const TQStringList& ) : TDECModule(MediaFactory::instance(), parent, name ) { - TDEGlobal::locale()->insertCatalogue("kio_media"); + TDEGlobal::locale()->insertCatalogue("tdeio_media"); TQVBoxLayout *layout = new TQVBoxLayout( this, 0, KDialog::spacingHint() ); TQTabWidget *tab = new TQTabWidget( this ); diff --git a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp index 20e68e459..dc46e8287 100644 --- a/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp +++ b/tdeioslave/media/tdefile-plugin/tdefilemediaplugin.cpp @@ -39,7 +39,7 @@ #endif typedef KGenericFactory KFileMediaPluginFactory; -K_EXPORT_COMPONENT_FACTORY(tdefile_media, KFileMediaPluginFactory("kio_media")) +K_EXPORT_COMPONENT_FACTORY(tdefile_media, KFileMediaPluginFactory("tdeio_media")) KFileMediaPlugin::KFileMediaPlugin(TQObject *parent, const char *name, const TQStringList& args) diff --git a/tdeioslave/media/tdeio_media.cpp b/tdeioslave/media/tdeio_media.cpp new file mode 100644 index 000000000..c8af18133 --- /dev/null +++ b/tdeioslave/media/tdeio_media.cpp @@ -0,0 +1,276 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "mediaimpl.h" +#include "tdeio_media.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 ) + { + // TDEApplication is necessary to use other ioslaves + putenv(strdup("SESSION_MANAGER=")); + TDECmdLineArgs::init(argc, argv, "tdeio_media", 0, 0, 0, 0); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication app( false, false ); + // We want to be anonymous even if we use DCOP + app.dcopClient()->attach(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + MediaProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); + slave.dispatchLoop(); + return 0; + } +} + + +MediaProtocol::MediaProtocol(const TQCString &protocol, + const TQCString &pool, const TQCString &app) + : ForwardingSlaveBase(protocol, pool, app) +{ + connect( &m_impl, TQT_SIGNAL( warning( const TQString & ) ), + this, TQT_SLOT( slotWarning( const TQString & ) ) ); +} + +MediaProtocol::~MediaProtocol() +{ +} + +bool MediaProtocol::rewriteURL(const KURL &url, KURL &newUrl) +{ + TQString name, path; + + if ( !m_impl.parseURL(url, name, path) ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return false; + } + + + if ( !m_impl.realURL(name, path, newUrl) ) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return false; + } + + return true; +} + +void MediaProtocol::put(const KURL &url, int permissions, + bool overwrite, bool resume) +{ + kdDebug(1219) << "MediaProtocol::put: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, url.prettyURL()); + } + else + { + ForwardingSlaveBase::put(url, permissions, overwrite, resume); + } +} + +void MediaProtocol::rename(const KURL &src, const KURL &dest, bool overwrite) +{ + kdDebug(1219) << "MediaProtocol::rename: " << src << ", " << dest << ", " + << overwrite << endl; + + TQString src_name, src_path; + bool ok = m_impl.parseURL(src, src_name, src_path); + TQString dest_name, dest_path; + ok &= m_impl.parseURL(dest, dest_name, dest_path); + + if ( ok && src_path.isEmpty() && dest_path.isEmpty() + && src.protocol() == "media" && dest.protocol() == "media" ) + { + if (!m_impl.setUserLabel(src_name, dest_name)) + { + error(m_impl.lastErrorCode(), m_impl.lastErrorMessage()); + } + else + { + finished(); + } + } + else + { + ForwardingSlaveBase::rename(src, dest, overwrite); + } +} + +void MediaProtocol::mkdir(const KURL &url, int permissions) +{ + kdDebug(1219) << "MediaProtocol::mkdir: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_COULD_NOT_MKDIR, url.prettyURL()); + } + else + { + ForwardingSlaveBase::mkdir(url, permissions); + } +} + +void MediaProtocol::del(const KURL &url, bool isFile) +{ + kdDebug(1219) << "MediaProtocol::del: " << url << endl; + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( ok && path.isEmpty() ) + { + error(TDEIO::ERR_CANNOT_DELETE, url.prettyURL()); + } + else + { + ForwardingSlaveBase::del(url, isFile); + } +} + +void MediaProtocol::stat(const KURL &url) +{ + kdDebug(1219) << "MediaProtocol::stat: " << url << endl; + TQString path = url.path(); + if( path.isEmpty() || path == "/" ) + { + // The root is "virtual" - it's not a single physical directory + TDEIO::UDSEntry entry; + m_impl.createTopLevelEntry( entry ); + statEntry( entry ); + finished(); + return; + } + + TQString name; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + if( path.isEmpty() ) + { + TDEIO::UDSEntry entry; + + if ( m_impl.statMedium(name, entry) + || m_impl.statMediumByLabel(name, entry) ) + { + statEntry(entry); + finished(); + } + else + { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + } + else + { + ForwardingSlaveBase::stat(url); + } +} + +void MediaProtocol::listDir(const KURL &url) +{ + kdDebug(1219) << "MediaProtocol::listDir: " << url << endl; + + if ( url.path().length() <= 1 ) + { + listRoot(); + return; + } + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + ForwardingSlaveBase::listDir(url); +} + +void MediaProtocol::listRoot() +{ + TDEIO::UDSEntry entry; + + TDEIO::UDSEntryList media_entries; + bool ok = m_impl.listMedia(media_entries); + + if (!ok) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return; + } + + totalSize(media_entries.count()+1); + + m_impl.createTopLevelEntry(entry); + listEntry(entry, false); + + TDEIO::UDSEntryListIterator it = media_entries.begin(); + TDEIO::UDSEntryListIterator end = media_entries.end(); + + for(; it!=end; ++it) + { + listEntry(*it, false); + } + + entry.clear(); + listEntry(entry, true); + + finished(); +} + +void MediaProtocol::slotWarning( const TQString &msg ) +{ + warning( msg ); +} + +#include "tdeio_media.moc" diff --git a/tdeioslave/media/tdeio_media.h b/tdeioslave/media/tdeio_media.h new file mode 100644 index 000000000..bf1325475 --- /dev/null +++ b/tdeioslave/media/tdeio_media.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KIO_MEDIA_H_ +#define _KIO_MEDIA_H_ + +#include + +#include "mediaimpl.h" + +class MediaProtocol : public TDEIO::ForwardingSlaveBase +{ +Q_OBJECT +public: + MediaProtocol(const TQCString &protocol, const TQCString &pool, + const TQCString &app); + virtual ~MediaProtocol(); + + virtual bool rewriteURL(const KURL &url, KURL &newUrl); + + virtual void put(const KURL &url, int permissions, + bool overwrite, bool resume); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void mkdir(const KURL &url, int permissions); + virtual void del(const KURL &url, bool isFile); + virtual void stat(const KURL &url); + virtual void listDir(const KURL &url); + +private slots: + void slotWarning( const TQString &msg ); + +private: + void listRoot(); + + MediaImpl m_impl; +}; + +#endif diff --git a/tdeioslave/media/testmedia.cpp b/tdeioslave/media/testmedia.cpp index eb0871f6f..ebd4f6b53 100644 --- a/tdeioslave/media/testmedia.cpp +++ b/tdeioslave/media/testmedia.cpp @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -#include "kio_media.h" +#include "tdeio_media.h" #include "testmedia.h" #include diff --git a/tdeioslave/nfs/CMakeLists.txt b/tdeioslave/nfs/CMakeLists.txt index da9040fc9..c6ccd04f8 100644 --- a/tdeioslave/nfs/CMakeLists.txt +++ b/tdeioslave/nfs/CMakeLists.txt @@ -26,9 +26,9 @@ link_directories( install( FILES nfs.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_nfs (module) ########################## +##### tdeio_nfs (module) ########################## -set( target kio_nfs ) +set( target tdeio_nfs ) add_custom_command( OUTPUT mount_xdr.c COMMAND rpcgen -c -o mount_xdr.c ${CMAKE_CURRENT_SOURCE_DIR}/mount.x @@ -39,7 +39,7 @@ add_custom_command( OUTPUT nfs_prot_xdr.c DEPENDS nfs_prot.x ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_nfs.cpp mount_xdr.c nfs_prot_xdr.c + SOURCES tdeio_nfs.cpp mount_xdr.c nfs_prot_xdr.c LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/nfs/Makefile.am b/tdeioslave/nfs/Makefile.am index 4ab02fc1d..0857fa223 100644 --- a/tdeioslave/nfs/Makefile.am +++ b/tdeioslave/nfs/Makefile.am @@ -5,11 +5,11 @@ AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB ####### Files -kde_module_LTLIBRARIES = kio_nfs.la +kde_module_LTLIBRARIES = tdeio_nfs.la -kio_nfs_la_SOURCES = kio_nfs.cpp mount_xdr.c nfs_prot_xdr.c -kio_nfs_la_LIBADD = -lkio $(LIBRPC) -kio_nfs_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_nfs_la_SOURCES = tdeio_nfs.cpp mount_xdr.c nfs_prot_xdr.c +tdeio_nfs_la_LIBADD = -ltdeio $(LIBRPC) +tdeio_nfs_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = nfs_prot.h mount.h kdelnk_DATA = nfs.protocol diff --git a/tdeioslave/nfs/kio_nfs.cpp b/tdeioslave/nfs/kio_nfs.cpp deleted file mode 100644 index 8148a7745..000000000 --- a/tdeioslave/nfs/kio_nfs.cpp +++ /dev/null @@ -1,1615 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2000 Alexander Neundorf - - 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. -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include - -// This is needed on Solaris so that rpc.h defines clnttcp_create etc. -#ifndef PORTMAP -#define PORTMAP -#endif -#include // for rpc calls - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include - -#include "nfs_prot.h" -#define fhandle _fhandle -#include "mount.h" -#include "kio_nfs.h" - -#define MAXHOSTLEN 256 - -//#define MAXFHAGE 60*15 //15 minutes maximum age for file handles - -//this ioslave is for NFS version 2 -#define NFSPROG ((u_long)100003) -#define NFSVERS ((u_long)2) - -using namespace TDEIO; -using namespace std; - -//this is taken from tdelibs/tdecore/fakes.cpp -//#if !defined(HAVE_GETDOMAINNAME) - -int x_getdomainname(char *name, size_t len) -{ - struct utsname uts; - struct hostent *hent; - int rv = -1; - - if (name == 0L) - errno = EINVAL; - else - { - name[0] = '\0'; - if (uname(&uts) >= 0) - { - if ((hent = gethostbyname(uts.nodename)) != 0L) - { - char *p = strchr(hent->h_name, '.'); - if (p != 0L) - { - ++p; - if (strlen(p) > len-1) - errno = EINVAL; - else - { - strcpy(name, p); - rv = 0; - } - } - } - } - } - return rv; -} -//#endif - - -extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } - -int kdemain( int argc, char **argv ) -{ - TDEInstance instance( "kio_nfs" ); - - if (argc != 4) - { - fprintf(stderr, "Usage: kio_nfs protocol domain-socket1 domain-socket2\n"); - exit(-1); - } - kdDebug(7121) << "NFS: kdemain: starting" << endl; - - NFSProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - return 0; -} - -static bool isRoot(const TQString& path) -{ - return (path.isEmpty() || (path=="/")); -} - -static bool isAbsoluteLink(const TQString& path) -{ - //hmm, don't know - if (path.isEmpty()) return TRUE; - if (path[0]=='/') return TRUE; - return FALSE; -} - -static void createVirtualDirEntry(UDSEntry & entry) -{ - UDSAtom atom; - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_USER; - atom.m_str = "root"; - entry.append( atom ); - atom.m_uds = TDEIO::UDS_GROUP; - atom.m_str = "root"; - entry.append( atom ); - - //a dummy size - atom.m_uds = TDEIO::UDS_SIZE; - atom.m_long = 1024; - entry.append( atom ); -} - - -static void stripTrailingSlash(TQString& path) -{ - //if (path=="/") return; - if (path=="/") path=""; - else if (path[path.length()-1]=='/') path.truncate(path.length()-1); -} - -static void getLastPart(const TQString& path, TQString& lastPart, TQString& rest) -{ - int slashPos=path.findRev("/"); - lastPart=path.mid(slashPos+1); - rest=path.left(slashPos+1); -} - -static TQString removeFirstPart(const TQString& path) -{ - TQString result(""); - if (path.isEmpty()) return result; - result=path.mid(1); - int slashPos=result.find("/"); - return result.mid(slashPos+1); -} - -NFSFileHandle::NFSFileHandle() -:m_isInvalid(FALSE) -{ - memset(m_handle,'\0',NFS_FHSIZE+1); -// m_detectTime=time(0); -} - -NFSFileHandle::NFSFileHandle(const NFSFileHandle & handle) -:m_isInvalid(FALSE) -{ - m_handle[NFS_FHSIZE]='\0'; - memcpy(m_handle,handle.m_handle,NFS_FHSIZE); - m_isInvalid=handle.m_isInvalid; -// m_detectTime=handle.m_detectTime; -} - -NFSFileHandle::~NFSFileHandle() -{} - -NFSFileHandle& NFSFileHandle::operator= (const NFSFileHandle& src) -{ - memcpy(m_handle,src.m_handle,NFS_FHSIZE); - m_isInvalid=src.m_isInvalid; -// m_detectTime=src.m_detectTime; - return *this; -} - -NFSFileHandle& NFSFileHandle::operator= (const char* src) -{ - if (src==0) - { - m_isInvalid=TRUE; - return *this; - }; - memcpy(m_handle,src,NFS_FHSIZE); - m_isInvalid=FALSE; -// m_detectTime=time(0); - return *this; -} - -/*time_t NFSFileHandle::age() const -{ - return (time(0)-m_detectTime); -}*/ - - -NFSProtocol::NFSProtocol (const TQCString &pool, const TQCString &app ) -:SlaveBase( "nfs", pool, app ) -,m_client(0) -,m_sock(-1) -,m_lastCheck(time(0)) -{ - kdDebug(7121)<<"NFS::NFS: -"<MAXFHAGE) - { - kdDebug(7121)<<"removing"<MAXFHAGE) checkForOldFHs(); - - stripTrailingSlash(path); - kdDebug(7121)<<"getting FH for -"<= '0' && m_currentHost[0] <= '9') - { - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = inet_addr(m_currentHost.latin1()); - } - else - { - struct hostent *hp=gethostbyname(m_currentHost.latin1()); - if (hp==0) - { - error( ERR_UNKNOWN_HOST, m_currentHost.latin1() ); - return; - } - server_addr.sin_family = AF_INET; - memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); - } - - // create mount deamon client - closeConnection(); - server_addr.sin_port = 0; - m_sock = RPC_ANYSOCK; - m_client=clnttcp_create(&server_addr,MOUNTPROG, MOUNTVERS, &m_sock, 0, 0); - if (m_client==0) - { - server_addr.sin_port = 0; - m_sock = RPC_ANYSOCK; - pertry_timeout.tv_sec = 3; - pertry_timeout.tv_usec = 0; - m_client = clntudp_create(&server_addr,MOUNTPROG, MOUNTVERS, pertry_timeout, &m_sock); - if (m_client==0) - { - clnt_pcreateerror(const_cast("mount clntudp_create")); - error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); - return; - } - } - TQCString hostName("localhost"); - char nameBuffer[1024]; - nameBuffer[0] = '\0'; - if (gethostname(nameBuffer, 1024)==0) - { - nameBuffer[sizeof(nameBuffer)-1] = '\0'; - hostName=nameBuffer; - // I have the same problem here as Stefan Westerfeld, that's why I use - // the getdomainname() from fakes.cpp (renamed to x_getdomainname()), this one works - // taken from tdelibs/arts/mcopy/mcoputils.cc - nameBuffer[0] = '\0'; - if (x_getdomainname(nameBuffer, 1024)==0) - { - nameBuffer[sizeof(nameBuffer)-1] = '\0'; - /* - * I don't know why, but on my linux machine, the domainname - * always ends up being (none), which is certainly no valid - * domainname - */ - if(strcmp(nameBuffer,"(none)") != 0) { - hostName += "."; - hostName += nameBuffer; - } - } - } - kdDebug(7121) << "hostname is -" << hostName << "-" << endl; - m_client->cl_auth = authunix_create(hostName.data(), geteuid(), getegid(), 0, 0); - total_timeout.tv_sec = 20; - total_timeout.tv_usec = 0; - - exports exportlist; - //now do the stuff - memset(&exportlist, '\0', sizeof(exportlist)); - - int clnt_stat = clnt_call(m_client, MOUNTPROC_EXPORT,(xdrproc_t) xdr_void, NULL, - (xdrproc_t) xdr_exports, (char*)&exportlist,total_timeout); - if (!checkForError(clnt_stat, 0, m_currentHost.latin1())) return; - - fhstatus fhStatus; - bool atLeastOnceSucceeded(FALSE); - for(; exportlist!=0;exportlist = exportlist->ex_next) { - kdDebug(7121) << "found export: " << exportlist->ex_dir << endl; - - memset(&fhStatus, 0, sizeof(fhStatus)); - clnt_stat = clnt_call(m_client, MOUNTPROC_MNT,(xdrproc_t) xdr_dirpath, (char*)(&(exportlist->ex_dir)), - (xdrproc_t) xdr_fhstatus,(char*) &fhStatus,total_timeout); - if (fhStatus.fhs_status==0) { - atLeastOnceSucceeded=TRUE; - NFSFileHandle fh; - fh=fhStatus.fhstatus_u.fhs_fhandle; - TQString fname; - if ( exportlist->ex_dir[0] == '/' ) - fname = TDEIO::encodeFileName(exportlist->ex_dir + 1); - else - fname = TDEIO::encodeFileName(exportlist->ex_dir); - m_handleCache.insert(TQString("/")+fname,fh); - m_exportedDirs.append(fname); - // kdDebug() <<"appending file -"<("NFS clntudp_create")); - error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); - return; - } - } - m_client->cl_auth = authunix_create(hostName.data(),geteuid(),getegid(),0,0); - connected(); - kdDebug(7121)<<"openConnection succeeded"<nextentry) - { - if ((TQString(".")!=dirEntry->name) && (TQString("..")!=dirEntry->name)) - filesToList.append(dirEntry->name); - } - } while (!listres.readdirres_u.reply.eof); - totalSize( filesToList.count()); - - UDSEntry entry; - //stat all files in filesToList - for (TQStringList::Iterator it=filesToList.begin(); it!=filesToList.end(); it++) - { - UDSAtom atom; - diropargs dirargs; - diropres dirres; - memcpy(dirargs.dir.data,fh,NFS_FHSIZE); - TQCString tmpStr=TQFile::encodeName(*it); - dirargs.name=tmpStr.data(); - - kdDebug(7121)<<"calling rpc: FH: -"<1) && (tmpPath[0]=='/')) tmpPath=tmpPath.mid(1); - // We can't stat root, but we know it's a dir - if (isRoot(path) || isExportedDir(path)) - { - UDSEntry entry; - UDSAtom atom; - - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = path; - entry.append( atom ); - createVirtualDirEntry(entry); - // no size - statEntry( entry ); - finished(); - kdDebug(7121)<<"succeeded"<pw_name)) ); - atom.m_str = user->pw_name; - } - else - atom.m_str = "???"; - } - else - atom.m_str = *temp; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_GROUP; - gid_t gid = buff.st_gid; - temp = m_groupcache.find( gid ); - if ( !temp ) - { - struct group *grp = getgrgid( gid ); - if ( grp ) - { - m_groupcache.insert( gid, new TQString(TQString::fromLatin1(grp->gr_name)) ); - atom.m_str = grp->gr_name; - } - else - atom.m_str = "???"; - } - else - atom.m_str = *temp; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS_TIME; - atom.m_long = buff.st_atime; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_CREATION_TIME; - atom.m_long = buff.st_ctime; - entry.append( atom ); -} - -void NFSProtocol::completeBadLinkUDSEntry(UDSEntry& entry, fattr& attributes) -{ - // It is a link pointing to nowhere - completeUDSEntry(entry,attributes); - - UDSAtom atom; - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFMT - 1; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = S_IRWXU | S_IRWXG | S_IRWXO; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_SIZE; - atom.m_long = 0L; - entry.append( atom ); -} - -void NFSProtocol::completeUDSEntry(UDSEntry& entry, fattr& attributes) -{ - UDSAtom atom; - - atom.m_uds = TDEIO::UDS_SIZE; - atom.m_long = attributes.size; - entry.append(atom); - - atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; - atom.m_long = attributes.mtime.seconds; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS_TIME; - atom.m_long = attributes.atime.seconds; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_CREATION_TIME; - atom.m_long = attributes.ctime.seconds; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = (attributes.mode & 07777); - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long =attributes.mode & S_IFMT; // extract file type - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_USER; - uid_t uid = attributes.uid; - TQString *temp = m_usercache.find( uid ); - if ( !temp ) - { - struct passwd *user = getpwuid( uid ); - if ( user ) - { - m_usercache.insert( uid, new TQString(user->pw_name) ); - atom.m_str = user->pw_name; - } - else - atom.m_str = "???"; - } - else - atom.m_str = *temp; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_GROUP; - gid_t gid = attributes.gid; - temp = m_groupcache.find( gid ); - if ( !temp ) - { - struct group *grp = getgrgid( gid ); - if ( grp ) - { - m_groupcache.insert( gid, new TQString(grp->gr_name) ); - atom.m_str = grp->gr_name; - } - else - atom.m_str = "???"; - } - else - atom.m_str = *temp; - entry.append( atom ); - -/* TDEIO::UDSEntry::ConstIterator it = entry.begin(); - for( ; it != entry.end(); it++ ) { - switch ((*it).m_uds) { - case TDEIO::UDS_FILE_TYPE: - kdDebug(7121) << "File Type : " << (mode_t)((*it).m_long) << endl; - break; - case TDEIO::UDS_ACCESS: - kdDebug(7121) << "Access permissions : " << (mode_t)((*it).m_long) << endl; - break; - case TDEIO::UDS_USER: - kdDebug(7121) << "User : " << ((*it).m_str.ascii() ) << endl; - break; - case TDEIO::UDS_GROUP: - kdDebug(7121) << "Group : " << ((*it).m_str.ascii() ) << endl; - break; - case TDEIO::UDS_NAME: - kdDebug(7121) << "Name : " << ((*it).m_str.ascii() ) << endl; - //m_strText = decodeFileName( (*it).m_str ); - break; - case TDEIO::UDS_URL: - kdDebug(7121) << "URL : " << ((*it).m_str.ascii() ) << endl; - break; - case TDEIO::UDS_MIME_TYPE: - kdDebug(7121) << "MimeType : " << ((*it).m_str.ascii() ) << endl; - break; - case TDEIO::UDS_LINK_DEST: - kdDebug(7121) << "LinkDest : " << ((*it).m_str.ascii() ) << endl; - break; - } - }*/ -} - -void NFSProtocol::setHost(const TQString& host, int /*port*/, const TQString& /*user*/, const TQString& /*pass*/) -{ - kdDebug(7121)<<"setHost: -"<0) - { - array.setRawData(readRes.readres_u.reply.data.data_val, offset); - data( array ); - array.resetRawData(readRes.readres_u.reply.data.data_val, offset); - - processedSize(readArgs.offset); - } - - } while (offset>0); - data( TQByteArray() ); - finished(); -} - -//TODO the partial putting thing is not yet implemented -void NFSProtocol::put( const KURL& url, int _mode, bool _overwrite, bool /*_resume*/ ) -{ - TQString destPath( TQFile::encodeName(url.path())); - kdDebug( 7121 ) << "Put -" << destPath <<"-"< 0) - { - do - { - if (bytesToWrite>NFS_MAXDATA) - { - writeNow=NFS_MAXDATA; - } - else - { - writeNow=bytesToWrite; - }; - writeArgs.data.data_val=data; - writeArgs.data.data_len=writeNow; - - int clnt_stat = clnt_call(m_client, NFSPROC_WRITE, - (xdrproc_t) xdr_writeargs, (char*)&writeArgs, - (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); - //kdDebug(7121)<<"written"<0); - } - } while ( result > 0 ); - finished(); -} - -void NFSProtocol::rename( const KURL &src, const KURL &dest, bool _overwrite ) -{ - TQString srcPath( TQFile::encodeName(src.path())); - TQString destPath( TQFile::encodeName(dest.path())); - stripTrailingSlash(srcPath); - stripTrailingSlash(destPath); - kdDebug(7121)<<"renaming -"<0) - { - readArgs.offset+=bytesRead; - - writeArgs.data.data_len=bytesRead; - - clnt_stat = clnt_call(m_client, NFSPROC_WRITE, - (xdrproc_t) xdr_writeargs, (char*)&writeArgs, - (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); - //kdDebug(7121)<<"written"<0); - - finished(); -} - -//TODO why isn't this even called ? -void NFSProtocol::symlink( const TQString &target, const KURL &dest, bool ) -{ - kdDebug(7121)<<"symlinking "< - - 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_NFS_H -#define KIO_NFS_H - -#include -#include - -#include -#include -#include -#include -#include - -#define PORTMAP //this seems to be required to compile on Solaris -#include -#include -#include -#include - -class NFSFileHandle -{ - public: - NFSFileHandle(); - NFSFileHandle(const NFSFileHandle & handle); - ~NFSFileHandle(); - NFSFileHandle& operator= (const NFSFileHandle& src); - NFSFileHandle& operator= (const char* src); - operator const char* () const {return m_handle;} - bool isInvalid() const {return m_isInvalid;} - void setInvalid() {m_isInvalid=TRUE;} -// time_t age() const; - protected: - char m_handle[NFS_FHSIZE+1]; - bool m_isInvalid; -// time_t m_detectTime; -}; - -//ostream& operator<<(ostream&, const NFSFileHandle&); - -typedef TQMap NFSFileHandleMap; - - -class NFSProtocol : public TDEIO::SlaveBase -{ - public: - NFSProtocol (const TQCString &pool, const TQCString &app ); - virtual ~NFSProtocol(); - - virtual void openConnection(); - virtual void closeConnection(); - - virtual void setHost( const TQString& host, int port, const TQString& user, const TQString& pass ); - - virtual void put( const KURL& url, int _mode,bool _overwrite, bool _resume ); - virtual void get( const KURL& url ); - virtual void listDir( const KURL& url); - virtual void symlink( const TQString &target, const KURL &dest, bool ); - virtual void stat( const KURL & url); - virtual void mkdir( const KURL& url, int permissions ); - virtual void del( const KURL& url, bool isfile); - virtual void chmod(const KURL& url, int permissions ); - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - virtual void copy( const KURL& src, const KURL &dest, int mode, bool overwrite ); - protected: -// void createVirtualDirEntry(TDEIO::UDSEntry & entry); - bool checkForError(int clientStat, int nfsStat, const TQString& text); - bool isExportedDir(const TQString& path); - void completeUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); - void completeBadLinkUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); - void completeAbsoluteLinkUDSEntry(TDEIO::UDSEntry& entry, const TQCString& path); - bool isValidLink(const TQString& parentDir, const TQString& linkDest); -// bool isAbsoluteLink(const TQString& path); - - NFSFileHandle getFileHandle(TQString path); - - NFSFileHandleMap m_handleCache; - TQIntDict m_usercache; // maps long ==> TQString * - TQIntDict m_groupcache; - - TQStringList m_exportedDirs; - TQString m_currentHost; - CLIENT *m_client; - CLIENT *m_nfsClient; - timeval total_timeout; - timeval pertry_timeout; - int m_sock; - time_t m_lastCheck; - void checkForOldFHs(); -}; - -#endif diff --git a/tdeioslave/nfs/nfs.protocol b/tdeioslave/nfs/nfs.protocol index 8f62d779a..faaa442e1 100644 --- a/tdeioslave/nfs/nfs.protocol +++ b/tdeioslave/nfs/nfs.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_nfs +exec=tdeio_nfs protocol=nfs input=none output=filesystem diff --git a/tdeioslave/nfs/tdeio_nfs.cpp b/tdeioslave/nfs/tdeio_nfs.cpp new file mode 100644 index 000000000..d0051e10b --- /dev/null +++ b/tdeioslave/nfs/tdeio_nfs.cpp @@ -0,0 +1,1615 @@ +/* This file is part of the KDE project + + Copyright (C) 2000 Alexander Neundorf + + 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. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +// This is needed on Solaris so that rpc.h defines clnttcp_create etc. +#ifndef PORTMAP +#define PORTMAP +#endif +#include // for rpc calls + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "nfs_prot.h" +#define fhandle _fhandle +#include "mount.h" +#include "tdeio_nfs.h" + +#define MAXHOSTLEN 256 + +//#define MAXFHAGE 60*15 //15 minutes maximum age for file handles + +//this ioslave is for NFS version 2 +#define NFSPROG ((u_long)100003) +#define NFSVERS ((u_long)2) + +using namespace TDEIO; +using namespace std; + +//this is taken from tdelibs/tdecore/fakes.cpp +//#if !defined(HAVE_GETDOMAINNAME) + +int x_getdomainname(char *name, size_t len) +{ + struct utsname uts; + struct hostent *hent; + int rv = -1; + + if (name == 0L) + errno = EINVAL; + else + { + name[0] = '\0'; + if (uname(&uts) >= 0) + { + if ((hent = gethostbyname(uts.nodename)) != 0L) + { + char *p = strchr(hent->h_name, '.'); + if (p != 0L) + { + ++p; + if (strlen(p) > len-1) + errno = EINVAL; + else + { + strcpy(name, p); + rv = 0; + } + } + } + } + } + return rv; +} +//#endif + + +extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } + +int kdemain( int argc, char **argv ) +{ + TDEInstance instance( "tdeio_nfs" ); + + if (argc != 4) + { + fprintf(stderr, "Usage: tdeio_nfs protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + kdDebug(7121) << "NFS: kdemain: starting" << endl; + + NFSProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; +} + +static bool isRoot(const TQString& path) +{ + return (path.isEmpty() || (path=="/")); +} + +static bool isAbsoluteLink(const TQString& path) +{ + //hmm, don't know + if (path.isEmpty()) return TRUE; + if (path[0]=='/') return TRUE; + return FALSE; +} + +static void createVirtualDirEntry(UDSEntry & entry) +{ + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + atom.m_str = "root"; + entry.append( atom ); + atom.m_uds = TDEIO::UDS_GROUP; + atom.m_str = "root"; + entry.append( atom ); + + //a dummy size + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = 1024; + entry.append( atom ); +} + + +static void stripTrailingSlash(TQString& path) +{ + //if (path=="/") return; + if (path=="/") path=""; + else if (path[path.length()-1]=='/') path.truncate(path.length()-1); +} + +static void getLastPart(const TQString& path, TQString& lastPart, TQString& rest) +{ + int slashPos=path.findRev("/"); + lastPart=path.mid(slashPos+1); + rest=path.left(slashPos+1); +} + +static TQString removeFirstPart(const TQString& path) +{ + TQString result(""); + if (path.isEmpty()) return result; + result=path.mid(1); + int slashPos=result.find("/"); + return result.mid(slashPos+1); +} + +NFSFileHandle::NFSFileHandle() +:m_isInvalid(FALSE) +{ + memset(m_handle,'\0',NFS_FHSIZE+1); +// m_detectTime=time(0); +} + +NFSFileHandle::NFSFileHandle(const NFSFileHandle & handle) +:m_isInvalid(FALSE) +{ + m_handle[NFS_FHSIZE]='\0'; + memcpy(m_handle,handle.m_handle,NFS_FHSIZE); + m_isInvalid=handle.m_isInvalid; +// m_detectTime=handle.m_detectTime; +} + +NFSFileHandle::~NFSFileHandle() +{} + +NFSFileHandle& NFSFileHandle::operator= (const NFSFileHandle& src) +{ + memcpy(m_handle,src.m_handle,NFS_FHSIZE); + m_isInvalid=src.m_isInvalid; +// m_detectTime=src.m_detectTime; + return *this; +} + +NFSFileHandle& NFSFileHandle::operator= (const char* src) +{ + if (src==0) + { + m_isInvalid=TRUE; + return *this; + }; + memcpy(m_handle,src,NFS_FHSIZE); + m_isInvalid=FALSE; +// m_detectTime=time(0); + return *this; +} + +/*time_t NFSFileHandle::age() const +{ + return (time(0)-m_detectTime); +}*/ + + +NFSProtocol::NFSProtocol (const TQCString &pool, const TQCString &app ) +:SlaveBase( "nfs", pool, app ) +,m_client(0) +,m_sock(-1) +,m_lastCheck(time(0)) +{ + kdDebug(7121)<<"NFS::NFS: -"<MAXFHAGE) + { + kdDebug(7121)<<"removing"<MAXFHAGE) checkForOldFHs(); + + stripTrailingSlash(path); + kdDebug(7121)<<"getting FH for -"<= '0' && m_currentHost[0] <= '9') + { + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(m_currentHost.latin1()); + } + else + { + struct hostent *hp=gethostbyname(m_currentHost.latin1()); + if (hp==0) + { + error( ERR_UNKNOWN_HOST, m_currentHost.latin1() ); + return; + } + server_addr.sin_family = AF_INET; + memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); + } + + // create mount deamon client + closeConnection(); + server_addr.sin_port = 0; + m_sock = RPC_ANYSOCK; + m_client=clnttcp_create(&server_addr,MOUNTPROG, MOUNTVERS, &m_sock, 0, 0); + if (m_client==0) + { + server_addr.sin_port = 0; + m_sock = RPC_ANYSOCK; + pertry_timeout.tv_sec = 3; + pertry_timeout.tv_usec = 0; + m_client = clntudp_create(&server_addr,MOUNTPROG, MOUNTVERS, pertry_timeout, &m_sock); + if (m_client==0) + { + clnt_pcreateerror(const_cast("mount clntudp_create")); + error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); + return; + } + } + TQCString hostName("localhost"); + char nameBuffer[1024]; + nameBuffer[0] = '\0'; + if (gethostname(nameBuffer, 1024)==0) + { + nameBuffer[sizeof(nameBuffer)-1] = '\0'; + hostName=nameBuffer; + // I have the same problem here as Stefan Westerfeld, that's why I use + // the getdomainname() from fakes.cpp (renamed to x_getdomainname()), this one works + // taken from tdelibs/arts/mcopy/mcoputils.cc + nameBuffer[0] = '\0'; + if (x_getdomainname(nameBuffer, 1024)==0) + { + nameBuffer[sizeof(nameBuffer)-1] = '\0'; + /* + * I don't know why, but on my linux machine, the domainname + * always ends up being (none), which is certainly no valid + * domainname + */ + if(strcmp(nameBuffer,"(none)") != 0) { + hostName += "."; + hostName += nameBuffer; + } + } + } + kdDebug(7121) << "hostname is -" << hostName << "-" << endl; + m_client->cl_auth = authunix_create(hostName.data(), geteuid(), getegid(), 0, 0); + total_timeout.tv_sec = 20; + total_timeout.tv_usec = 0; + + exports exportlist; + //now do the stuff + memset(&exportlist, '\0', sizeof(exportlist)); + + int clnt_stat = clnt_call(m_client, MOUNTPROC_EXPORT,(xdrproc_t) xdr_void, NULL, + (xdrproc_t) xdr_exports, (char*)&exportlist,total_timeout); + if (!checkForError(clnt_stat, 0, m_currentHost.latin1())) return; + + fhstatus fhStatus; + bool atLeastOnceSucceeded(FALSE); + for(; exportlist!=0;exportlist = exportlist->ex_next) { + kdDebug(7121) << "found export: " << exportlist->ex_dir << endl; + + memset(&fhStatus, 0, sizeof(fhStatus)); + clnt_stat = clnt_call(m_client, MOUNTPROC_MNT,(xdrproc_t) xdr_dirpath, (char*)(&(exportlist->ex_dir)), + (xdrproc_t) xdr_fhstatus,(char*) &fhStatus,total_timeout); + if (fhStatus.fhs_status==0) { + atLeastOnceSucceeded=TRUE; + NFSFileHandle fh; + fh=fhStatus.fhstatus_u.fhs_fhandle; + TQString fname; + if ( exportlist->ex_dir[0] == '/' ) + fname = TDEIO::encodeFileName(exportlist->ex_dir + 1); + else + fname = TDEIO::encodeFileName(exportlist->ex_dir); + m_handleCache.insert(TQString("/")+fname,fh); + m_exportedDirs.append(fname); + // kdDebug() <<"appending file -"<("NFS clntudp_create")); + error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); + return; + } + } + m_client->cl_auth = authunix_create(hostName.data(),geteuid(),getegid(),0,0); + connected(); + kdDebug(7121)<<"openConnection succeeded"<nextentry) + { + if ((TQString(".")!=dirEntry->name) && (TQString("..")!=dirEntry->name)) + filesToList.append(dirEntry->name); + } + } while (!listres.readdirres_u.reply.eof); + totalSize( filesToList.count()); + + UDSEntry entry; + //stat all files in filesToList + for (TQStringList::Iterator it=filesToList.begin(); it!=filesToList.end(); it++) + { + UDSAtom atom; + diropargs dirargs; + diropres dirres; + memcpy(dirargs.dir.data,fh,NFS_FHSIZE); + TQCString tmpStr=TQFile::encodeName(*it); + dirargs.name=tmpStr.data(); + + kdDebug(7121)<<"calling rpc: FH: -"<1) && (tmpPath[0]=='/')) tmpPath=tmpPath.mid(1); + // We can't stat root, but we know it's a dir + if (isRoot(path) || isExportedDir(path)) + { + UDSEntry entry; + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = path; + entry.append( atom ); + createVirtualDirEntry(entry); + // no size + statEntry( entry ); + finished(); + kdDebug(7121)<<"succeeded"<pw_name)) ); + atom.m_str = user->pw_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_GROUP; + gid_t gid = buff.st_gid; + temp = m_groupcache.find( gid ); + if ( !temp ) + { + struct group *grp = getgrgid( gid ); + if ( grp ) + { + m_groupcache.insert( gid, new TQString(TQString::fromLatin1(grp->gr_name)) ); + atom.m_str = grp->gr_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS_TIME; + atom.m_long = buff.st_atime; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_CREATION_TIME; + atom.m_long = buff.st_ctime; + entry.append( atom ); +} + +void NFSProtocol::completeBadLinkUDSEntry(UDSEntry& entry, fattr& attributes) +{ + // It is a link pointing to nowhere + completeUDSEntry(entry,attributes); + + UDSAtom atom; + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFMT - 1; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = S_IRWXU | S_IRWXG | S_IRWXO; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = 0L; + entry.append( atom ); +} + +void NFSProtocol::completeUDSEntry(UDSEntry& entry, fattr& attributes) +{ + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = attributes.size; + entry.append(atom); + + atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; + atom.m_long = attributes.mtime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS_TIME; + atom.m_long = attributes.atime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_CREATION_TIME; + atom.m_long = attributes.ctime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = (attributes.mode & 07777); + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long =attributes.mode & S_IFMT; // extract file type + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + uid_t uid = attributes.uid; + TQString *temp = m_usercache.find( uid ); + if ( !temp ) + { + struct passwd *user = getpwuid( uid ); + if ( user ) + { + m_usercache.insert( uid, new TQString(user->pw_name) ); + atom.m_str = user->pw_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_GROUP; + gid_t gid = attributes.gid; + temp = m_groupcache.find( gid ); + if ( !temp ) + { + struct group *grp = getgrgid( gid ); + if ( grp ) + { + m_groupcache.insert( gid, new TQString(grp->gr_name) ); + atom.m_str = grp->gr_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + +/* TDEIO::UDSEntry::ConstIterator it = entry.begin(); + for( ; it != entry.end(); it++ ) { + switch ((*it).m_uds) { + case TDEIO::UDS_FILE_TYPE: + kdDebug(7121) << "File Type : " << (mode_t)((*it).m_long) << endl; + break; + case TDEIO::UDS_ACCESS: + kdDebug(7121) << "Access permissions : " << (mode_t)((*it).m_long) << endl; + break; + case TDEIO::UDS_USER: + kdDebug(7121) << "User : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_GROUP: + kdDebug(7121) << "Group : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_NAME: + kdDebug(7121) << "Name : " << ((*it).m_str.ascii() ) << endl; + //m_strText = decodeFileName( (*it).m_str ); + break; + case TDEIO::UDS_URL: + kdDebug(7121) << "URL : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_MIME_TYPE: + kdDebug(7121) << "MimeType : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_LINK_DEST: + kdDebug(7121) << "LinkDest : " << ((*it).m_str.ascii() ) << endl; + break; + } + }*/ +} + +void NFSProtocol::setHost(const TQString& host, int /*port*/, const TQString& /*user*/, const TQString& /*pass*/) +{ + kdDebug(7121)<<"setHost: -"<0) + { + array.setRawData(readRes.readres_u.reply.data.data_val, offset); + data( array ); + array.resetRawData(readRes.readres_u.reply.data.data_val, offset); + + processedSize(readArgs.offset); + } + + } while (offset>0); + data( TQByteArray() ); + finished(); +} + +//TODO the partial putting thing is not yet implemented +void NFSProtocol::put( const KURL& url, int _mode, bool _overwrite, bool /*_resume*/ ) +{ + TQString destPath( TQFile::encodeName(url.path())); + kdDebug( 7121 ) << "Put -" << destPath <<"-"< 0) + { + do + { + if (bytesToWrite>NFS_MAXDATA) + { + writeNow=NFS_MAXDATA; + } + else + { + writeNow=bytesToWrite; + }; + writeArgs.data.data_val=data; + writeArgs.data.data_len=writeNow; + + int clnt_stat = clnt_call(m_client, NFSPROC_WRITE, + (xdrproc_t) xdr_writeargs, (char*)&writeArgs, + (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); + //kdDebug(7121)<<"written"<0); + } + } while ( result > 0 ); + finished(); +} + +void NFSProtocol::rename( const KURL &src, const KURL &dest, bool _overwrite ) +{ + TQString srcPath( TQFile::encodeName(src.path())); + TQString destPath( TQFile::encodeName(dest.path())); + stripTrailingSlash(srcPath); + stripTrailingSlash(destPath); + kdDebug(7121)<<"renaming -"<0) + { + readArgs.offset+=bytesRead; + + writeArgs.data.data_len=bytesRead; + + clnt_stat = clnt_call(m_client, NFSPROC_WRITE, + (xdrproc_t) xdr_writeargs, (char*)&writeArgs, + (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); + //kdDebug(7121)<<"written"<0); + + finished(); +} + +//TODO why isn't this even called ? +void NFSProtocol::symlink( const TQString &target, const KURL &dest, bool ) +{ + kdDebug(7121)<<"symlinking "< + + 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_NFS_H +#define KIO_NFS_H + +#include +#include + +#include +#include +#include +#include +#include + +#define PORTMAP //this seems to be required to compile on Solaris +#include +#include +#include +#include + +class NFSFileHandle +{ + public: + NFSFileHandle(); + NFSFileHandle(const NFSFileHandle & handle); + ~NFSFileHandle(); + NFSFileHandle& operator= (const NFSFileHandle& src); + NFSFileHandle& operator= (const char* src); + operator const char* () const {return m_handle;} + bool isInvalid() const {return m_isInvalid;} + void setInvalid() {m_isInvalid=TRUE;} +// time_t age() const; + protected: + char m_handle[NFS_FHSIZE+1]; + bool m_isInvalid; +// time_t m_detectTime; +}; + +//ostream& operator<<(ostream&, const NFSFileHandle&); + +typedef TQMap NFSFileHandleMap; + + +class NFSProtocol : public TDEIO::SlaveBase +{ + public: + NFSProtocol (const TQCString &pool, const TQCString &app ); + virtual ~NFSProtocol(); + + virtual void openConnection(); + virtual void closeConnection(); + + virtual void setHost( const TQString& host, int port, const TQString& user, const TQString& pass ); + + virtual void put( const KURL& url, int _mode,bool _overwrite, bool _resume ); + virtual void get( const KURL& url ); + virtual void listDir( const KURL& url); + virtual void symlink( const TQString &target, const KURL &dest, bool ); + virtual void stat( const KURL & url); + virtual void mkdir( const KURL& url, int permissions ); + virtual void del( const KURL& url, bool isfile); + virtual void chmod(const KURL& url, int permissions ); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void copy( const KURL& src, const KURL &dest, int mode, bool overwrite ); + protected: +// void createVirtualDirEntry(TDEIO::UDSEntry & entry); + bool checkForError(int clientStat, int nfsStat, const TQString& text); + bool isExportedDir(const TQString& path); + void completeUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); + void completeBadLinkUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); + void completeAbsoluteLinkUDSEntry(TDEIO::UDSEntry& entry, const TQCString& path); + bool isValidLink(const TQString& parentDir, const TQString& linkDest); +// bool isAbsoluteLink(const TQString& path); + + NFSFileHandle getFileHandle(TQString path); + + NFSFileHandleMap m_handleCache; + TQIntDict m_usercache; // maps long ==> TQString * + TQIntDict m_groupcache; + + TQStringList m_exportedDirs; + TQString m_currentHost; + CLIENT *m_client; + CLIENT *m_nfsClient; + timeval total_timeout; + timeval pertry_timeout; + int m_sock; + time_t m_lastCheck; + void checkForOldFHs(); +}; + +#endif diff --git a/tdeioslave/nntp/CMakeLists.txt b/tdeioslave/nntp/CMakeLists.txt index d3401c455..3fb4ed1c6 100644 --- a/tdeioslave/nntp/CMakeLists.txt +++ b/tdeioslave/nntp/CMakeLists.txt @@ -25,9 +25,9 @@ link_directories( install( FILES nntp.protocol nntps.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_nntp (module) ######################### +##### tdeio_nntp (module) ######################### -set( target kio_nntp ) +set( target tdeio_nntp ) tde_add_kpart( ${target} AUTOMOC SOURCES nntp.cpp diff --git a/tdeioslave/nntp/Makefile.am b/tdeioslave/nntp/Makefile.am index a48a7de80..9f1b322eb 100644 --- a/tdeioslave/nntp/Makefile.am +++ b/tdeioslave/nntp/Makefile.am @@ -2,11 +2,11 @@ INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(all_includes) ####### Files -kde_module_LTLIBRARIES = kio_nntp.la +kde_module_LTLIBRARIES = tdeio_nntp.la -kio_nntp_la_SOURCES = nntp.cpp -kio_nntp_la_LIBADD = $(LIB_KIO) -kio_nntp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_nntp_la_SOURCES = nntp.cpp +tdeio_nntp_la_LIBADD = $(LIB_KIO) +tdeio_nntp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) METASOURCES = AUTO diff --git a/tdeioslave/nntp/nntp.cpp b/tdeioslave/nntp/nntp.cpp index b92ff6a30..7353e0e2e 100644 --- a/tdeioslave/nntp/nntp.cpp +++ b/tdeioslave/nntp/nntp.cpp @@ -39,9 +39,9 @@ extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } int kdemain(int argc, char **argv) { - TDEInstance instance ("kio_nntp"); + TDEInstance instance ("tdeio_nntp"); if (argc != 4) { - fprintf(stderr, "Usage: kio_nntp protocol domain-socket1 domain-socket2\n"); + fprintf(stderr, "Usage: tdeio_nntp protocol domain-socket1 domain-socket2\n"); exit(-1); } diff --git a/tdeioslave/nntp/nntp.protocol b/tdeioslave/nntp/nntp.protocol index 8a51f88fb..ed5754bb6 100644 --- a/tdeioslave/nntp/nntp.protocol +++ b/tdeioslave/nntp/nntp.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_nntp +exec=tdeio_nntp protocol=nntp input=none output=filesystem diff --git a/tdeioslave/nntp/nntps.protocol b/tdeioslave/nntp/nntps.protocol index dd975d250..aafa37218 100644 --- a/tdeioslave/nntp/nntps.protocol +++ b/tdeioslave/nntp/nntps.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_nntp +exec=tdeio_nntp protocol=nntps input=none output=filesystem diff --git a/tdeioslave/pop3/CMakeLists.txt b/tdeioslave/pop3/CMakeLists.txt index a5fcaf2da..fb0dbcbb1 100644 --- a/tdeioslave/pop3/CMakeLists.txt +++ b/tdeioslave/pop3/CMakeLists.txt @@ -26,9 +26,9 @@ link_directories( install( FILES pop3.protocol pop3s.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_pop3 (module) ######################### +##### tdeio_pop3 (module) ######################### -set( target kio_pop3 ) +set( target tdeio_pop3 ) tde_add_kpart( ${target} AUTOMOC SOURCES pop3.cc diff --git a/tdeioslave/pop3/Makefile.am b/tdeioslave/pop3/Makefile.am index 86d649b66..1bd5c95e5 100644 --- a/tdeioslave/pop3/Makefile.am +++ b/tdeioslave/pop3/Makefile.am @@ -2,11 +2,11 @@ INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(SSL_INCLUDES) $(all_includes) ####### Files -kde_module_LTLIBRARIES = kio_pop3.la +kde_module_LTLIBRARIES = tdeio_pop3.la -kio_pop3_la_SOURCES = pop3.cc -kio_pop3_la_LIBADD = $(LIB_KIO) $(SASL2_LIBS) -kio_pop3_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_pop3_la_SOURCES = pop3.cc +tdeio_pop3_la_LIBADD = $(LIB_KIO) $(SASL2_LIBS) +tdeio_pop3_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = pop3.h diff --git a/tdeioslave/pop3/pop3.cc b/tdeioslave/pop3/pop3.cc index e4518da08..9b45f47f3 100644 --- a/tdeioslave/pop3/pop3.cc +++ b/tdeioslave/pop3/pop3.cc @@ -92,7 +92,7 @@ int kdemain(int argc, char **argv) { if (argc != 4) { - POP3_DEBUG << "Usage: kio_pop3 protocol domain-socket1 domain-socket2" + POP3_DEBUG << "Usage: tdeio_pop3 protocol domain-socket1 domain-socket2" << endl; return -1; } @@ -104,7 +104,7 @@ int kdemain(int argc, char **argv) } #endif - TDEInstance instance("kio_pop3"); + TDEInstance instance("tdeio_pop3"); POP3Protocol *slave; // Are we looking to use SSL? @@ -599,7 +599,7 @@ int POP3Protocol::loginSASL( TDEIO::AuthInfo &ai ) #else if (metaData("auth") == "SASL") { closeConnection(); - error(ERR_COULD_NOT_LOGIN, i18n("SASL authentication is not compiled into kio_pop3.")); + error(ERR_COULD_NOT_LOGIN, i18n("SASL authentication is not compiled into tdeio_pop3.")); return -1; } return 1; //if SASL not explicitly required, try another method (USER/PASS) diff --git a/tdeioslave/pop3/pop3.protocol b/tdeioslave/pop3/pop3.protocol index 23560fa48..7aa3e442f 100644 --- a/tdeioslave/pop3/pop3.protocol +++ b/tdeioslave/pop3/pop3.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_pop3 +exec=tdeio_pop3 protocol=pop3 Capabilities=SASL input=none diff --git a/tdeioslave/pop3/pop3s.protocol b/tdeioslave/pop3/pop3s.protocol index 8bcf0c899..772f72d37 100644 --- a/tdeioslave/pop3/pop3s.protocol +++ b/tdeioslave/pop3/pop3s.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_pop3 +exec=tdeio_pop3 protocol=pop3s Capabilities=SASL input=none diff --git a/tdeioslave/remote/CMakeLists.txt b/tdeioslave/remote/CMakeLists.txt index fe4c29154..82e7c1fd1 100644 --- a/tdeioslave/remote/CMakeLists.txt +++ b/tdeioslave/remote/CMakeLists.txt @@ -27,24 +27,24 @@ link_directories( install( FILES remote.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kioremote (static) ######################## +##### tdeioremote (static) ######################## -set( target kioremote ) +set( target tdeioremote ) tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES kio_remote.cpp remoteimpl.cpp + SOURCES tdeio_remote.cpp remoteimpl.cpp ) -##### kio_remote (module) ####################### +##### tdeio_remote (module) ####################### -set( target kio_remote ) +set( target tdeio_remote ) configure_file( ${CMAKE_SOURCE_DIR}/cmake/modules/template_dummy_cpp.cmake dummy.cpp COPYONLY ) tde_add_kpart( ${target} SOURCES dummy.cpp - EMBED kioremote-static + EMBED tdeioremote-static LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/remote/Makefile.am b/tdeioslave/remote/Makefile.am index 4acb4e999..780e0ac36 100644 --- a/tdeioslave/remote/Makefile.am +++ b/tdeioslave/remote/Makefile.am @@ -4,11 +4,11 @@ SUBDIRS= . kdedmodule INCLUDES = $(all_includes) METASOURCES = AUTO -kde_module_LTLIBRARIES = kio_remote.la +kde_module_LTLIBRARIES = tdeio_remote.la -kio_remote_la_SOURCES = dummy.cpp -kio_remote_la_LIBADD = libtdeioremote.la $(LIB_KIO) -kio_remote_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined +tdeio_remote_la_SOURCES = dummy.cpp +tdeio_remote_la_LIBADD = libtdeioremote.la $(LIB_KIO) +tdeio_remote_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined dummy.cpp: echo > dummy.cpp @@ -16,7 +16,7 @@ dummy.cpp: kde_services_DATA = remote.protocol noinst_LTLIBRARIES = libtdeioremote.la -libtdeioremote_la_SOURCES = kio_remote.cpp remoteimpl.cpp +libtdeioremote_la_SOURCES = tdeio_remote.cpp remoteimpl.cpp check_PROGRAMS = testremote testremote_SOURCES = testremote.cpp diff --git a/tdeioslave/remote/kdedmodule/remotedirnotifymodule.cpp b/tdeioslave/remote/kdedmodule/remotedirnotifymodule.cpp index 13bfcfc29..04b7a2bee 100644 --- a/tdeioslave/remote/kdedmodule/remotedirnotifymodule.cpp +++ b/tdeioslave/remote/kdedmodule/remotedirnotifymodule.cpp @@ -30,7 +30,7 @@ RemoteDirNotifyModule::RemoteDirNotifyModule(const TQCString &obj) extern "C" { KDE_EXPORT KDEDModule *create_remotedirnotify(const TQCString &obj) { - TDEGlobal::locale()->insertCatalogue("kio_remote"); + TDEGlobal::locale()->insertCatalogue("tdeio_remote"); return new RemoteDirNotifyModule(obj); } } diff --git a/tdeioslave/remote/kio_remote.cpp b/tdeioslave/remote/kio_remote.cpp deleted file mode 100644 index 87437700f..000000000 --- a/tdeioslave/remote/kio_remote.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include -#include -#include -#include -#include - - -#include "kio_remote.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 ) - { - // TDEApplication is necessary to use other ioslaves - putenv(strdup("SESSION_MANAGER=")); - TDECmdLineArgs::init(argc, argv, "kio_remote", 0, 0, 0, 0); - TDECmdLineArgs::addCmdLineOptions( options ); - TDEApplication app( false, false ); - // We want to be anonymous even if we use DCOP - app.dcopClient()->attach(); - - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - RemoteProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); - slave.dispatchLoop(); - return 0; - } -} - - -RemoteProtocol::RemoteProtocol(const TQCString &protocol, - const TQCString &pool, const TQCString &app) - : SlaveBase(protocol, pool, app) -{ -} - -RemoteProtocol::~RemoteProtocol() -{ -} - -void RemoteProtocol::listDir(const KURL &url) -{ - kdDebug(1220) << "RemoteProtocol::listDir: " << url << endl; - - if ( url.path().length() <= 1 ) - { - listRoot(); - return; - } - - int second_slash_idx = url.path().find( '/', 1 ); - TQString root_dirname = url.path().mid( 1, second_slash_idx-1 ); - - KURL target = m_impl.findBaseURL( root_dirname ); - kdDebug(1220) << "possible redirection target : " << target << endl; - if( target.isValid() ) - { - target.addPath( url.path().remove(0, second_slash_idx) ); - redirection(target); - finished(); - return; - } - - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); -} - -void RemoteProtocol::listRoot() -{ - TDEIO::UDSEntry entry; - - TDEIO::UDSEntryList remote_entries; - m_impl.listRoot(remote_entries); - - totalSize(remote_entries.count()+2); - - m_impl.createTopLevelEntry(entry); - listEntry(entry, false); - - m_impl.createWizardEntry(entry); - listEntry(entry, false); - - TDEIO::UDSEntryListIterator it = remote_entries.begin(); - TDEIO::UDSEntryListIterator end = remote_entries.end(); - - for(; it!=end; ++it) - { - listEntry(*it, false); - } - - entry.clear(); - listEntry(entry, true); - - finished(); -} - -void RemoteProtocol::stat(const KURL &url) -{ - kdDebug(1220) << "RemoteProtocol::stat: " << url << endl; - - TQString path = url.path(); - if ( path.isEmpty() || path == "/" ) - { - // The root is "virtual" - it's not a single physical directory - TDEIO::UDSEntry entry; - m_impl.createTopLevelEntry( entry ); - statEntry( entry ); - finished(); - return; - } - - if (m_impl.isWizardURL(url)) - { - TDEIO::UDSEntry entry; - if (m_impl.createWizardEntry(entry)) - { - statEntry(entry); - finished(); - } - else - { - error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - } - return; - } - - int second_slash_idx = url.path().find( '/', 1 ); - TQString root_dirname = url.path().mid( 1, second_slash_idx-1 ); - - if ( second_slash_idx==-1 || ( (int)url.path().length() )==second_slash_idx+1 ) - { - TDEIO::UDSEntry entry; - if (m_impl.statNetworkFolder(entry, root_dirname)) - { - statEntry(entry); - finished(); - return; - } - } - else - { - KURL target = m_impl.findBaseURL( root_dirname ); - kdDebug( 1220 ) << "possible redirection target : " << target << endl; - if ( target.isValid() ) - { - target.addPath( url.path().remove( 0, second_slash_idx ) ); - redirection( target ); - finished(); - return; - } - } - - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); -} - -void RemoteProtocol::del(const KURL &url, bool /*isFile*/) -{ - kdDebug(1220) << "RemoteProtocol::del: " << url << endl; - - if (!m_impl.isWizardURL(url) - && m_impl.deleteNetworkFolder(url.fileName())) - { - finished(); - return; - } - - error(TDEIO::ERR_CANNOT_DELETE, url.prettyURL()); -} - -void RemoteProtocol::get(const KURL &url) -{ - kdDebug(1220) << "RemoteProtocol::get: " << url << endl; - - TQString file = m_impl.findDesktopFile( url.fileName() ); - kdDebug(1220) << "desktop file : " << file << endl; - - if (!file.isEmpty()) - { - KURL desktop; - desktop.setPath(file); - - redirection(desktop); - finished(); - return; - } - - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); -} - -void RemoteProtocol::rename(const KURL &src, const KURL &dest, - bool overwrite) -{ - if (src.protocol()!="remote" || dest.protocol()!="remote" - || m_impl.isWizardURL(src) || m_impl.isWizardURL(dest)) - { - error(TDEIO::ERR_UNSUPPORTED_ACTION, src.prettyURL()); - return; - } - - if (m_impl.renameFolders(src.fileName(), dest.fileName(), overwrite)) - { - finished(); - return; - } - - error(TDEIO::ERR_CANNOT_RENAME, src.prettyURL()); -} diff --git a/tdeioslave/remote/kio_remote.h b/tdeioslave/remote/kio_remote.h deleted file mode 100644 index ebc6dd1ad..000000000 --- a/tdeioslave/remote/kio_remote.h +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KIO_REMOTE_H -#define KIO_REMOTE_H - -#include -#include "remoteimpl.h" - -class RemoteProtocol : public TDEIO::SlaveBase -{ -public: - RemoteProtocol(const TQCString &protocol, const TQCString &pool, - const TQCString &app); - virtual ~RemoteProtocol(); - - virtual void listDir(const KURL &url); - virtual void stat(const KURL &url); - virtual void del(const KURL &url, bool isFile); - virtual void get(const KURL &url); - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - -private: - void listRoot(); - - RemoteImpl m_impl; -}; - -#endif diff --git a/tdeioslave/remote/remote.protocol b/tdeioslave/remote/remote.protocol index 69cc638aa..2d28b3a47 100644 --- a/tdeioslave/remote/remote.protocol +++ b/tdeioslave/remote/remote.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_remote +exec=tdeio_remote protocol=remote input=none output=filesystem diff --git a/tdeioslave/remote/tdeio_remote.cpp b/tdeioslave/remote/tdeio_remote.cpp new file mode 100644 index 000000000..d4522de3e --- /dev/null +++ b/tdeioslave/remote/tdeio_remote.cpp @@ -0,0 +1,234 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include +#include + + +#include "tdeio_remote.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 ) + { + // TDEApplication is necessary to use other ioslaves + putenv(strdup("SESSION_MANAGER=")); + TDECmdLineArgs::init(argc, argv, "tdeio_remote", 0, 0, 0, 0); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication app( false, false ); + // We want to be anonymous even if we use DCOP + app.dcopClient()->attach(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + RemoteProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); + slave.dispatchLoop(); + return 0; + } +} + + +RemoteProtocol::RemoteProtocol(const TQCString &protocol, + const TQCString &pool, const TQCString &app) + : SlaveBase(protocol, pool, app) +{ +} + +RemoteProtocol::~RemoteProtocol() +{ +} + +void RemoteProtocol::listDir(const KURL &url) +{ + kdDebug(1220) << "RemoteProtocol::listDir: " << url << endl; + + if ( url.path().length() <= 1 ) + { + listRoot(); + return; + } + + int second_slash_idx = url.path().find( '/', 1 ); + TQString root_dirname = url.path().mid( 1, second_slash_idx-1 ); + + KURL target = m_impl.findBaseURL( root_dirname ); + kdDebug(1220) << "possible redirection target : " << target << endl; + if( target.isValid() ) + { + target.addPath( url.path().remove(0, second_slash_idx) ); + redirection(target); + finished(); + return; + } + + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); +} + +void RemoteProtocol::listRoot() +{ + TDEIO::UDSEntry entry; + + TDEIO::UDSEntryList remote_entries; + m_impl.listRoot(remote_entries); + + totalSize(remote_entries.count()+2); + + m_impl.createTopLevelEntry(entry); + listEntry(entry, false); + + m_impl.createWizardEntry(entry); + listEntry(entry, false); + + TDEIO::UDSEntryListIterator it = remote_entries.begin(); + TDEIO::UDSEntryListIterator end = remote_entries.end(); + + for(; it!=end; ++it) + { + listEntry(*it, false); + } + + entry.clear(); + listEntry(entry, true); + + finished(); +} + +void RemoteProtocol::stat(const KURL &url) +{ + kdDebug(1220) << "RemoteProtocol::stat: " << url << endl; + + TQString path = url.path(); + if ( path.isEmpty() || path == "/" ) + { + // The root is "virtual" - it's not a single physical directory + TDEIO::UDSEntry entry; + m_impl.createTopLevelEntry( entry ); + statEntry( entry ); + finished(); + return; + } + + if (m_impl.isWizardURL(url)) + { + TDEIO::UDSEntry entry; + if (m_impl.createWizardEntry(entry)) + { + statEntry(entry); + finished(); + } + else + { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + return; + } + + int second_slash_idx = url.path().find( '/', 1 ); + TQString root_dirname = url.path().mid( 1, second_slash_idx-1 ); + + if ( second_slash_idx==-1 || ( (int)url.path().length() )==second_slash_idx+1 ) + { + TDEIO::UDSEntry entry; + if (m_impl.statNetworkFolder(entry, root_dirname)) + { + statEntry(entry); + finished(); + return; + } + } + else + { + KURL target = m_impl.findBaseURL( root_dirname ); + kdDebug( 1220 ) << "possible redirection target : " << target << endl; + if ( target.isValid() ) + { + target.addPath( url.path().remove( 0, second_slash_idx ) ); + redirection( target ); + finished(); + return; + } + } + + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); +} + +void RemoteProtocol::del(const KURL &url, bool /*isFile*/) +{ + kdDebug(1220) << "RemoteProtocol::del: " << url << endl; + + if (!m_impl.isWizardURL(url) + && m_impl.deleteNetworkFolder(url.fileName())) + { + finished(); + return; + } + + error(TDEIO::ERR_CANNOT_DELETE, url.prettyURL()); +} + +void RemoteProtocol::get(const KURL &url) +{ + kdDebug(1220) << "RemoteProtocol::get: " << url << endl; + + TQString file = m_impl.findDesktopFile( url.fileName() ); + kdDebug(1220) << "desktop file : " << file << endl; + + if (!file.isEmpty()) + { + KURL desktop; + desktop.setPath(file); + + redirection(desktop); + finished(); + return; + } + + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); +} + +void RemoteProtocol::rename(const KURL &src, const KURL &dest, + bool overwrite) +{ + if (src.protocol()!="remote" || dest.protocol()!="remote" + || m_impl.isWizardURL(src) || m_impl.isWizardURL(dest)) + { + error(TDEIO::ERR_UNSUPPORTED_ACTION, src.prettyURL()); + return; + } + + if (m_impl.renameFolders(src.fileName(), dest.fileName(), overwrite)) + { + finished(); + return; + } + + error(TDEIO::ERR_CANNOT_RENAME, src.prettyURL()); +} diff --git a/tdeioslave/remote/tdeio_remote.h b/tdeioslave/remote/tdeio_remote.h new file mode 100644 index 000000000..ebc6dd1ad --- /dev/null +++ b/tdeioslave/remote/tdeio_remote.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIO_REMOTE_H +#define KIO_REMOTE_H + +#include +#include "remoteimpl.h" + +class RemoteProtocol : public TDEIO::SlaveBase +{ +public: + RemoteProtocol(const TQCString &protocol, const TQCString &pool, + const TQCString &app); + virtual ~RemoteProtocol(); + + virtual void listDir(const KURL &url); + virtual void stat(const KURL &url); + virtual void del(const KURL &url, bool isFile); + virtual void get(const KURL &url); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + +private: + void listRoot(); + + RemoteImpl m_impl; +}; + +#endif diff --git a/tdeioslave/remote/testremote.cpp b/tdeioslave/remote/testremote.cpp index d091c5bc4..3071772a9 100644 --- a/tdeioslave/remote/testremote.cpp +++ b/tdeioslave/remote/testremote.cpp @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -#include "kio_remote.h" +#include "tdeio_remote.h" #include "testremote.h" #include diff --git a/tdeioslave/settings/CMakeLists.txt b/tdeioslave/settings/CMakeLists.txt index c2a0d1d06..9b723f8b4 100644 --- a/tdeioslave/settings/CMakeLists.txt +++ b/tdeioslave/settings/CMakeLists.txt @@ -27,12 +27,12 @@ install( FILES DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_settings (module) ##################### +##### tdeio_settings (module) ##################### -set( target kio_settings ) +set( target tdeio_settings ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_settings.cc + SOURCES tdeio_settings.cc LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/settings/Makefile.am b/tdeioslave/settings/Makefile.am index 7daa4e009..2c2ac9320 100644 --- a/tdeioslave/settings/Makefile.am +++ b/tdeioslave/settings/Makefile.am @@ -2,13 +2,13 @@ INCLUDES= $(all_includes) ####### Files -kde_module_LTLIBRARIES = kio_settings.la +kde_module_LTLIBRARIES = tdeio_settings.la -kio_settings_la_SOURCES = kio_settings.cc -kio_settings_la_LIBADD = $(LIB_KSYCOCA) -kio_settings_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_settings_la_SOURCES = tdeio_settings.cc +tdeio_settings_la_LIBADD = $(LIB_KSYCOCA) +tdeio_settings_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_settings.h +noinst_HEADERS = tdeio_settings.h kdelnk_DATA = settings.protocol programs.protocol applications.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/settings/applications.protocol b/tdeioslave/settings/applications.protocol index 0193dfb8b..7d35ae254 100644 --- a/tdeioslave/settings/applications.protocol +++ b/tdeioslave/settings/applications.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_settings +exec=tdeio_settings protocol=applications input=none output=filesystem diff --git a/tdeioslave/settings/kio_settings.cc b/tdeioslave/settings/kio_settings.cc deleted file mode 100644 index 7060df177..000000000 --- a/tdeioslave/settings/kio_settings.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Joseph Wenninger - - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SettingsProtocol : public TDEIO::SlaveBase -{ -public: - enum RunMode { SettingsMode, ProgramsMode, ApplicationsMode }; - SettingsProtocol(const TQCString &protocol, const TQCString &pool, const TQCString &app); - virtual ~SettingsProtocol(); - virtual void get( const KURL& url ); - virtual void stat(const KURL& url); - virtual void listDir(const KURL& url); - void listRoot(); - KServiceGroup::Ptr findGroup(const TQString &relPath); - -private: - DCOPClient *m_dcopClient; - RunMode m_runMode; -}; - -extern "C" { - KDE_EXPORT int kdemain( int, char **argv ) - { - kdDebug() << "kdemain for settings tdeioslave" << endl; - TDEInstance instance( "kio_settings" ); - SettingsProtocol slave(argv[1], argv[2], argv[3]); - slave.dispatchLoop(); - return 0; - } -} - - -static void addAtom(TDEIO::UDSEntry& entry, unsigned int ID, 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); -} - -static void createFileEntry(TDEIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime, const TQString& iconName, const TQString& localPath) -{ - entry.clear(); - addAtom(entry, TDEIO::UDS_NAME, 0, TDEIO::encodeFileName(name)); - addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFREG); - addAtom(entry, TDEIO::UDS_URL, 0, url); - addAtom(entry, TDEIO::UDS_ACCESS, 0500); - addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, mime); - addAtom(entry, TDEIO::UDS_SIZE, 0); - addAtom(entry, TDEIO::UDS_LOCAL_PATH, 0, localPath); - addAtom(entry, TDEIO::UDS_CREATION_TIME, 1); - addAtom(entry, TDEIO::UDS_MODIFICATION_TIME, time(0)); - addAtom(entry, TDEIO::UDS_ICON_NAME, 0, iconName); -} - -static void createDirEntry(TDEIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime,const TQString& iconName) -{ - entry.clear(); - addAtom(entry, TDEIO::UDS_NAME, 0, name); - addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); - addAtom(entry, TDEIO::UDS_ACCESS, 0500); - addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, mime); - addAtom(entry, TDEIO::UDS_URL, 0, url); - addAtom(entry, TDEIO::UDS_SIZE, 0); - addAtom(entry, TDEIO::UDS_ICON_NAME, 0, iconName); -} - -SettingsProtocol::SettingsProtocol( const TQCString &protocol, const TQCString &pool, const TQCString &app): SlaveBase( protocol, pool, app ) -{ - // Adjusts which part of the TDE Menu to virtualize. - if ( protocol == "programs" ) - m_runMode = ProgramsMode; - else - if (protocol == "applications") - m_runMode = ApplicationsMode; - else - m_runMode = SettingsMode; - - m_dcopClient = new DCOPClient(); - if (!m_dcopClient->attach()) - { - kdDebug() << "ERROR WHILE CONNECTING TO DCOPSERVER" << endl; - } -} - -SettingsProtocol::~SettingsProtocol() -{ - delete m_dcopClient; -} - -KServiceGroup::Ptr SettingsProtocol::findGroup(const TQString &relPath) -{ - TQString nextPart; - TQString alreadyFound("Settings/"); - TQStringList rest = TQStringList::split('/', relPath); - - kdDebug() << "Trying harder to find group " << relPath << endl; - for (unsigned int i=0; iisValid()) - return 0; - - KServiceGroup::List list = tmp->entries(true, true); - KServiceGroup::List::ConstIterator it = list.begin(); - - bool found = false; - for (; it != list.end(); ++it) { - KSycocaEntry *e = *it; - if (e->isType(KST_KServiceGroup)) { - KServiceGroup::Ptr g(static_cast(e)); - if ((g->caption()==rest.front()) || (g->name()==alreadyFound+rest.front())) { - kdDebug() << "Found group with caption " << g->caption() - << " with real name: " << g->name() << endl; - found = true; - rest.remove(rest.begin()); - alreadyFound = g->name(); - kdDebug() << "ALREADY FOUND: " << alreadyFound << endl; - break; - } - } - } - - if (!found) { - kdDebug() << "Group with caption " << rest.front() << " not found within " - << alreadyFound << endl; - return 0; - } - - } - return KServiceGroup::group(alreadyFound); -} - -void SettingsProtocol::get( const KURL & url ) -{ - KService::Ptr service = KService::serviceByDesktopName(url.fileName()); - if (service && service->isValid()) { - KURL redirUrl; - redirUrl.setPath(locate("apps", service->desktopEntryPath())); - redirection(redirUrl); - finished(); - } else { - error( TDEIO::ERR_IS_DIRECTORY, url.prettyURL() ); - } -} - - -void SettingsProtocol::stat(const KURL& url) -{ - TDEIO::UDSEntry entry; - - TQString servicePath( url.path(1) ); - servicePath.remove(0, 1); // remove starting '/' - - if ( m_runMode == SettingsMode) - servicePath = "Settings/" + servicePath; - - KServiceGroup::Ptr grp = KServiceGroup::group(servicePath); - - if (grp && grp->isValid()) { - createDirEntry(entry, (m_runMode == SettingsMode) ? i18n("Settings") : ( (m_runMode==ApplicationsMode) ? i18n("Applications") : i18n("Programs")), - url.url(), "inode/directory",grp->icon() ); - } else { - KService::Ptr service = KService::serviceByDesktopName( url.fileName() ); - if (service && service->isValid()) { -// KURL newUrl; -// newUrl.setPath(locate("apps", service->desktopEntryPath())); -// createFileEntry(entry, service->name(), newUrl, "application/x-desktop", service->icon()); - - createFileEntry(entry, service->name(), url.url(1)+service->desktopEntryName(), - "application/x-desktop", service->icon(), locate("apps", service->desktopEntryPath()) ); - } else { - error(TDEIO::ERR_SLAVE_DEFINED,i18n("Unknown settings folder")); - return; - } - } - - statEntry(entry); - finished(); - return; -} - - -void SettingsProtocol::listDir(const KURL& url) -{ - TQString groupPath = url.path(1); - groupPath.remove(0, 1); // remove starting '/' - - if ( m_runMode == SettingsMode) - groupPath.prepend("Settings/"); - - KServiceGroup::Ptr grp = KServiceGroup::group(groupPath); - - if (!grp || !grp->isValid()) { - grp = findGroup(groupPath); - if (!grp || !grp->isValid()) { - error(TDEIO::ERR_SLAVE_DEFINED,i18n("Unknown settings folder")); - return; - } - } - - unsigned int count = 0; - TDEIO::UDSEntry entry; - - KServiceGroup::List list = grp->entries(true, true); - KServiceGroup::List::ConstIterator it; - - for (it = list.begin(); it != list.end(); ++it) { - KSycocaEntry * e = *it; - - if (e->isType(KST_KServiceGroup)) { - KServiceGroup::Ptr g(static_cast(e)); - TQString groupCaption = g->caption(); - - // Avoid adding empty groups. - KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath()); - if (subMenuRoot->childCount() == 0) - continue; - - // Ignore dotfiles. - if ((g->name().at(0) == '.')) - continue; - - TQString relPath = g->relPath(); - - // Do not display the "Settings" menu group in Programs Mode. - if( (m_runMode == ProgramsMode) && relPath.startsWith( "Settings" ) ) - { - kdDebug() << "SettingsProtocol: SKIPPING entry programs:/" << relPath << endl; - continue; - } - - switch( m_runMode ) - { - case( SettingsMode ): - relPath.remove(0, 9); // length("Settings/") ==9 - kdDebug() << "SettingsProtocol: adding entry settings:/" << relPath << endl; - createDirEntry(entry, groupCaption, "settings:/"+relPath, "inode/directory",g->icon()); - break; - case( ProgramsMode ): - kdDebug() << "SettingsProtocol: adding entry programs:/" << relPath << endl; - createDirEntry(entry, groupCaption, "programs:/"+relPath, "inode/directory",g->icon()); - break; - case( ApplicationsMode ): - kdDebug() << "SettingsProtocol: adding entry applications:/" << relPath << endl; - createDirEntry(entry, groupCaption, "applications:/"+relPath, "inode/directory",g->icon()); - break; - } - - } else { - KService::Ptr s(static_cast(e)); - kdDebug() << "SettingsProtocol: adding file entry " << url.url(1)+s->name() << endl; - createFileEntry(entry,s->name(),url.url(1)+s->desktopEntryName(), "application/x-desktop",s->icon(),locate("apps", s->desktopEntryPath())); - } - - listEntry(entry, false); - count++; - } - - totalSize(count); - listEntry(entry, true); - finished(); -} - -// vim: ts=4 sw=4 et diff --git a/tdeioslave/settings/kio_settings.h b/tdeioslave/settings/kio_settings.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/tdeioslave/settings/programs.protocol b/tdeioslave/settings/programs.protocol index c09ac6372..a02219d3e 100644 --- a/tdeioslave/settings/programs.protocol +++ b/tdeioslave/settings/programs.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_settings +exec=tdeio_settings protocol=programs input=none output=filesystem diff --git a/tdeioslave/settings/settings.protocol b/tdeioslave/settings/settings.protocol index 268bc0c69..a02ed9145 100644 --- a/tdeioslave/settings/settings.protocol +++ b/tdeioslave/settings/settings.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_settings +exec=tdeio_settings protocol=settings input=none output=filesystem diff --git a/tdeioslave/settings/tdeio_settings.cc b/tdeioslave/settings/tdeio_settings.cc new file mode 100644 index 000000000..47635693d --- /dev/null +++ b/tdeioslave/settings/tdeio_settings.cc @@ -0,0 +1,298 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Joseph Wenninger + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SettingsProtocol : public TDEIO::SlaveBase +{ +public: + enum RunMode { SettingsMode, ProgramsMode, ApplicationsMode }; + SettingsProtocol(const TQCString &protocol, const TQCString &pool, const TQCString &app); + virtual ~SettingsProtocol(); + virtual void get( const KURL& url ); + virtual void stat(const KURL& url); + virtual void listDir(const KURL& url); + void listRoot(); + KServiceGroup::Ptr findGroup(const TQString &relPath); + +private: + DCOPClient *m_dcopClient; + RunMode m_runMode; +}; + +extern "C" { + KDE_EXPORT int kdemain( int, char **argv ) + { + kdDebug() << "kdemain for settings tdeioslave" << endl; + TDEInstance instance( "tdeio_settings" ); + SettingsProtocol slave(argv[1], argv[2], argv[3]); + slave.dispatchLoop(); + return 0; + } +} + + +static void addAtom(TDEIO::UDSEntry& entry, unsigned int ID, 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); +} + +static void createFileEntry(TDEIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime, const TQString& iconName, const TQString& localPath) +{ + entry.clear(); + addAtom(entry, TDEIO::UDS_NAME, 0, TDEIO::encodeFileName(name)); + addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFREG); + addAtom(entry, TDEIO::UDS_URL, 0, url); + addAtom(entry, TDEIO::UDS_ACCESS, 0500); + addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, mime); + addAtom(entry, TDEIO::UDS_SIZE, 0); + addAtom(entry, TDEIO::UDS_LOCAL_PATH, 0, localPath); + addAtom(entry, TDEIO::UDS_CREATION_TIME, 1); + addAtom(entry, TDEIO::UDS_MODIFICATION_TIME, time(0)); + addAtom(entry, TDEIO::UDS_ICON_NAME, 0, iconName); +} + +static void createDirEntry(TDEIO::UDSEntry& entry, const TQString& name, const TQString& url, const TQString& mime,const TQString& iconName) +{ + entry.clear(); + addAtom(entry, TDEIO::UDS_NAME, 0, name); + addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); + addAtom(entry, TDEIO::UDS_ACCESS, 0500); + addAtom(entry, TDEIO::UDS_MIME_TYPE, 0, mime); + addAtom(entry, TDEIO::UDS_URL, 0, url); + addAtom(entry, TDEIO::UDS_SIZE, 0); + addAtom(entry, TDEIO::UDS_ICON_NAME, 0, iconName); +} + +SettingsProtocol::SettingsProtocol( const TQCString &protocol, const TQCString &pool, const TQCString &app): SlaveBase( protocol, pool, app ) +{ + // Adjusts which part of the TDE Menu to virtualize. + if ( protocol == "programs" ) + m_runMode = ProgramsMode; + else + if (protocol == "applications") + m_runMode = ApplicationsMode; + else + m_runMode = SettingsMode; + + m_dcopClient = new DCOPClient(); + if (!m_dcopClient->attach()) + { + kdDebug() << "ERROR WHILE CONNECTING TO DCOPSERVER" << endl; + } +} + +SettingsProtocol::~SettingsProtocol() +{ + delete m_dcopClient; +} + +KServiceGroup::Ptr SettingsProtocol::findGroup(const TQString &relPath) +{ + TQString nextPart; + TQString alreadyFound("Settings/"); + TQStringList rest = TQStringList::split('/', relPath); + + kdDebug() << "Trying harder to find group " << relPath << endl; + for (unsigned int i=0; iisValid()) + return 0; + + KServiceGroup::List list = tmp->entries(true, true); + KServiceGroup::List::ConstIterator it = list.begin(); + + bool found = false; + for (; it != list.end(); ++it) { + KSycocaEntry *e = *it; + if (e->isType(KST_KServiceGroup)) { + KServiceGroup::Ptr g(static_cast(e)); + if ((g->caption()==rest.front()) || (g->name()==alreadyFound+rest.front())) { + kdDebug() << "Found group with caption " << g->caption() + << " with real name: " << g->name() << endl; + found = true; + rest.remove(rest.begin()); + alreadyFound = g->name(); + kdDebug() << "ALREADY FOUND: " << alreadyFound << endl; + break; + } + } + } + + if (!found) { + kdDebug() << "Group with caption " << rest.front() << " not found within " + << alreadyFound << endl; + return 0; + } + + } + return KServiceGroup::group(alreadyFound); +} + +void SettingsProtocol::get( const KURL & url ) +{ + KService::Ptr service = KService::serviceByDesktopName(url.fileName()); + if (service && service->isValid()) { + KURL redirUrl; + redirUrl.setPath(locate("apps", service->desktopEntryPath())); + redirection(redirUrl); + finished(); + } else { + error( TDEIO::ERR_IS_DIRECTORY, url.prettyURL() ); + } +} + + +void SettingsProtocol::stat(const KURL& url) +{ + TDEIO::UDSEntry entry; + + TQString servicePath( url.path(1) ); + servicePath.remove(0, 1); // remove starting '/' + + if ( m_runMode == SettingsMode) + servicePath = "Settings/" + servicePath; + + KServiceGroup::Ptr grp = KServiceGroup::group(servicePath); + + if (grp && grp->isValid()) { + createDirEntry(entry, (m_runMode == SettingsMode) ? i18n("Settings") : ( (m_runMode==ApplicationsMode) ? i18n("Applications") : i18n("Programs")), + url.url(), "inode/directory",grp->icon() ); + } else { + KService::Ptr service = KService::serviceByDesktopName( url.fileName() ); + if (service && service->isValid()) { +// KURL newUrl; +// newUrl.setPath(locate("apps", service->desktopEntryPath())); +// createFileEntry(entry, service->name(), newUrl, "application/x-desktop", service->icon()); + + createFileEntry(entry, service->name(), url.url(1)+service->desktopEntryName(), + "application/x-desktop", service->icon(), locate("apps", service->desktopEntryPath()) ); + } else { + error(TDEIO::ERR_SLAVE_DEFINED,i18n("Unknown settings folder")); + return; + } + } + + statEntry(entry); + finished(); + return; +} + + +void SettingsProtocol::listDir(const KURL& url) +{ + TQString groupPath = url.path(1); + groupPath.remove(0, 1); // remove starting '/' + + if ( m_runMode == SettingsMode) + groupPath.prepend("Settings/"); + + KServiceGroup::Ptr grp = KServiceGroup::group(groupPath); + + if (!grp || !grp->isValid()) { + grp = findGroup(groupPath); + if (!grp || !grp->isValid()) { + error(TDEIO::ERR_SLAVE_DEFINED,i18n("Unknown settings folder")); + return; + } + } + + unsigned int count = 0; + TDEIO::UDSEntry entry; + + KServiceGroup::List list = grp->entries(true, true); + KServiceGroup::List::ConstIterator it; + + for (it = list.begin(); it != list.end(); ++it) { + KSycocaEntry * e = *it; + + if (e->isType(KST_KServiceGroup)) { + KServiceGroup::Ptr g(static_cast(e)); + TQString groupCaption = g->caption(); + + // Avoid adding empty groups. + KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath()); + if (subMenuRoot->childCount() == 0) + continue; + + // Ignore dotfiles. + if ((g->name().at(0) == '.')) + continue; + + TQString relPath = g->relPath(); + + // Do not display the "Settings" menu group in Programs Mode. + if( (m_runMode == ProgramsMode) && relPath.startsWith( "Settings" ) ) + { + kdDebug() << "SettingsProtocol: SKIPPING entry programs:/" << relPath << endl; + continue; + } + + switch( m_runMode ) + { + case( SettingsMode ): + relPath.remove(0, 9); // length("Settings/") ==9 + kdDebug() << "SettingsProtocol: adding entry settings:/" << relPath << endl; + createDirEntry(entry, groupCaption, "settings:/"+relPath, "inode/directory",g->icon()); + break; + case( ProgramsMode ): + kdDebug() << "SettingsProtocol: adding entry programs:/" << relPath << endl; + createDirEntry(entry, groupCaption, "programs:/"+relPath, "inode/directory",g->icon()); + break; + case( ApplicationsMode ): + kdDebug() << "SettingsProtocol: adding entry applications:/" << relPath << endl; + createDirEntry(entry, groupCaption, "applications:/"+relPath, "inode/directory",g->icon()); + break; + } + + } else { + KService::Ptr s(static_cast(e)); + kdDebug() << "SettingsProtocol: adding file entry " << url.url(1)+s->name() << endl; + createFileEntry(entry,s->name(),url.url(1)+s->desktopEntryName(), "application/x-desktop",s->icon(),locate("apps", s->desktopEntryPath())); + } + + listEntry(entry, false); + count++; + } + + totalSize(count); + listEntry(entry, true); + finished(); +} + +// vim: ts=4 sw=4 et diff --git a/tdeioslave/settings/tdeio_settings.h b/tdeioslave/settings/tdeio_settings.h new file mode 100644 index 000000000..e69de29bb diff --git a/tdeioslave/sftp/CHANGELOG b/tdeioslave/sftp/CHANGELOG index b60e7f44b..c34cd9dec 100644 --- a/tdeioslave/sftp/CHANGELOG +++ b/tdeioslave/sftp/CHANGELOG @@ -32,7 +32,7 @@ 7-22-2001 - probable solution to getting password prompt -- open with controlling but don't connect stdin/out to terminal. duh! 8-9-2001 - Doh! I haven't kept very good logs. Look at the cvs logs for better info. - - At this point kio_sftp is using KSshProcess which I wrote in order to make + - At this point tdeio_sftp is using KSshProcess which I wrote in order to make a standard interface to the various version of ssh out there. So far it is working fairly well. We also now report host key changes to the user and allow them to choose whether or not to continue. This is a big improvement. diff --git a/tdeioslave/sftp/CMakeLists.txt b/tdeioslave/sftp/CMakeLists.txt index cf07ed2b3..0cee3a838 100644 --- a/tdeioslave/sftp/CMakeLists.txt +++ b/tdeioslave/sftp/CMakeLists.txt @@ -26,12 +26,12 @@ link_directories( install( FILES sftp.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_sftp (module) ######################### +##### tdeio_sftp (module) ######################### -set( target kio_sftp ) +set( target tdeio_sftp ) tde_add_kpart( ${target} AUTOMOC - SOURCES process.cpp atomicio.cpp kio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp + SOURCES process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/sftp/Makefile.am b/tdeioslave/sftp/Makefile.am index 4bc14c203..d64f7567c 100644 --- a/tdeioslave/sftp/Makefile.am +++ b/tdeioslave/sftp/Makefile.am @@ -11,12 +11,12 @@ check_PROGRAMS = ksshprocesstest ksshprocesstest_SOURCES = ksshprocesstest.cpp ksshprocesstest_LDADD = $(LIB_KSYCOCA) ksshprocess.lo process.lo atomicio.lo -kde_module_LTLIBRARIES = kio_sftp.la +kde_module_LTLIBRARIES = tdeio_sftp.la -kio_sftp_la_SOURCES = process.cpp atomicio.cpp kio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp -kio_sftp_la_LIBADD = $(LIB_KIO) -kio_sftp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = atomicio.h kio_sftp.h ksshprocess.h process.h sftpfileattr.h sftp.h +tdeio_sftp_la_SOURCES = process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp +tdeio_sftp_la_LIBADD = $(LIB_KIO) +tdeio_sftp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +noinst_HEADERS = atomicio.h tdeio_sftp.h ksshprocess.h process.h sftpfileattr.h sftp.h kdelnk_DATA = sftp.protocol kdelnkdir = $(kde_servicesdir) diff --git a/tdeioslave/sftp/kio_sftp.cpp b/tdeioslave/sftp/kio_sftp.cpp deleted file mode 100644 index 719fb9136..000000000 --- a/tdeioslave/sftp/kio_sftp.cpp +++ /dev/null @@ -1,2282 +0,0 @@ -/*************************************************************************** - sftp.cpp - description - ------------------- - begin : Fri Jun 29 23:45:40 CDT 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu - ***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -/* -DEBUGGING -We are pretty much left with kdDebug messages for debugging. We can't use a gdb -as described in the ioslave DEBUG.howto because tdeinit has to run in a terminal. -Ssh will detect this terminal and ask for a password there, but will just get garbage. -So we can't connect. -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sftp.h" -#include "kio_sftp.h" -#include "atomicio.h" -#include "sftpfileattr.h" -#include "ksshprocess.h" - - -using namespace TDEIO; -extern "C" -{ - int KDE_EXPORT kdemain( int argc, char **argv ) - { - TDEInstance instance( "kio_sftp" ); - - kdDebug(KIO_SFTP_DB) << "*** Starting kio_sftp " << endl; - - if (argc != 4) { - kdDebug(KIO_SFTP_DB) << "Usage: kio_sftp protocol domain-socket1 domain-socket2" << endl; - exit(-1); - } - - sftpProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - kdDebug(KIO_SFTP_DB) << "*** kio_sftp Done" << endl; - return 0; - } -} - - -/* - * This helper handles some special issues (blocking and interrupted - * system call) when writing to a file handle. - * - * @return 0 on success or an error code on failure (ERR_COULD_NOT_WRITE, - * ERR_DISK_FULL, ERR_CONNECTION_BROKEN). - */ -static int writeToFile (int fd, const char *buf, size_t len) -{ - while (len > 0) - { - ssize_t written = ::write(fd, buf, len); - if (written >= 0) - { - buf += written; - len -= written; - continue; - } - - switch(errno) - { - case EINTR: - continue; - case EPIPE: - return ERR_CONNECTION_BROKEN; - case ENOSPC: - return ERR_DISK_FULL; - default: - return ERR_COULD_NOT_WRITE; - } - } - return 0; -} - -sftpProtocol::sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : SlaveBase("kio_sftp", pool_socket, app_socket), - mConnected(false), mPort(-1), mMsgId(0) { - kdDebug(KIO_SFTP_DB) << "sftpProtocol(): pid = " << getpid() << endl; -} - - -sftpProtocol::~sftpProtocol() { - kdDebug(KIO_SFTP_DB) << "~sftpProtocol(): pid = " << getpid() << endl; - closeConnection(); -} - -/** - * Type is a sftp packet type found in .sftp.h'. - * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. - * - * Returns true if the type is supported by the sftp protocol - * version negotiated by the client and server (sftpVersion). - */ -bool sftpProtocol::isSupportedOperation(int type) { - switch (type) { - case SSH2_FXP_VERSION: - case SSH2_FXP_STATUS: - case SSH2_FXP_HANDLE: - case SSH2_FXP_DATA: - case SSH2_FXP_NAME: - case SSH2_FXP_ATTRS: - case SSH2_FXP_INIT: - case SSH2_FXP_OPEN: - case SSH2_FXP_CLOSE: - case SSH2_FXP_READ: - case SSH2_FXP_WRITE: - case SSH2_FXP_LSTAT: - case SSH2_FXP_FSTAT: - case SSH2_FXP_SETSTAT: - case SSH2_FXP_FSETSTAT: - case SSH2_FXP_OPENDIR: - case SSH2_FXP_READDIR: - case SSH2_FXP_REMOVE: - case SSH2_FXP_MKDIR: - case SSH2_FXP_RMDIR: - case SSH2_FXP_REALPATH: - case SSH2_FXP_STAT: - return true; - case SSH2_FXP_RENAME: - return sftpVersion >= 2 ? true : false; - case SSH2_FXP_EXTENDED: - case SSH2_FXP_EXTENDED_REPLY: - case SSH2_FXP_READLINK: - case SSH2_FXP_SYMLINK: - return sftpVersion >= 3 ? true : false; - default: - kdDebug(KIO_SFTP_DB) << "isSupportedOperation(type:" - << type << "): unrecognized operation type" << endl; - break; - } - - return false; -} - -void sftpProtocol::copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) -{ - kdDebug(KIO_SFTP_DB) << "copy(): " << src << " -> " << dest << endl; - - bool srcLocal = src.isLocalFile(); - bool destLocal = dest.isLocalFile(); - - if ( srcLocal && !destLocal ) // Copy file -> sftp - sftpCopyPut(src, dest, permissions, overwrite); - else if ( destLocal && !srcLocal ) // Copy sftp -> file - sftpCopyGet(dest, src, permissions, overwrite); - else - error(ERR_UNSUPPORTED_ACTION, TQString::null); -} - -void sftpProtocol::sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite) -{ - kdDebug(KIO_SFTP_DB) << "sftpCopyGet(): " << src << " -> " << dest << endl; - - // Attempt to establish a connection... - openConnection(); - if( !mConnected ) - return; - - KDE_struct_stat buff_orig; - TQCString dest_orig ( TQFile::encodeName(dest.path()) ); - bool origExists = (KDE_lstat( dest_orig.data(), &buff_orig ) != -1); - - if (origExists) - { - if (S_ISDIR(buff_orig.st_mode)) - { - error(ERR_IS_DIRECTORY, dest.prettyURL()); - return; - } - - if (!overwrite) - { - error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); - return; - } - } - - TDEIO::filesize_t offset = 0; - TQCString dest_part ( dest_orig + ".part" ); - - int fd = -1; - bool partExists = false; - bool markPartial = config()->readBoolEntry("MarkPartial", true); - - if (markPartial) - { - KDE_struct_stat buff_part; - partExists = (KDE_stat( dest_part.data(), &buff_part ) != -1); - - if (partExists && buff_part.st_size > 0 && S_ISREG(buff_part.st_mode)) - { - if (canResume( buff_part.st_size )) - { - offset = buff_part.st_size; - kdDebug(KIO_SFTP_DB) << "sftpCopyGet: Resuming @ " << offset << endl; - } - } - - if (offset > 0) - { - fd = KDE_open(dest_part.data(), O_RDWR); - offset = KDE_lseek(fd, 0, SEEK_END); - if (offset == 0) - { - error(ERR_CANNOT_RESUME, dest.prettyURL()); - return; - } - } - else - { - // Set up permissions properly, based on what is done in file io-slave - int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); - int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); - fd = KDE_open(dest_part.data(), openFlags, initialMode); - } - } - else - { - // Set up permissions properly, based on what is done in file io-slave - int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); - int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); - fd = KDE_open(dest_orig.data(), openFlags, initialMode); - } - - if(fd == -1) - { - kdDebug(KIO_SFTP_DB) << "sftpCopyGet: Unable to open (" << fd << ") for writting." << endl; - if (errno == EACCES) - error (ERR_WRITE_ACCESS_DENIED, dest.prettyURL()); - else - error (ERR_CANNOT_OPEN_FOR_WRITING, dest.prettyURL()); - return; - } - - Status info = sftpGet(src, offset, fd); - if ( info.code != 0 ) - { - // Should we keep the partially downloaded file ?? - TDEIO::filesize_t size = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); - if (info.size < size) - ::remove(dest_part.data()); - - error(info.code, info.text); - return; - } - - if (::close(fd) != 0) - { - error(ERR_COULD_NOT_WRITE, dest.prettyURL()); - return; - } - - // - if (markPartial) - { - if (::rename(dest_part.data(), dest_orig.data()) != 0) - { - error (ERR_CANNOT_RENAME_PARTIAL, dest_part); - return; - } - } - - data(TQByteArray()); - kdDebug(KIO_SFTP_DB) << "sftpCopyGet(): emit finished()" << endl; - finished(); -} - -sftpProtocol::Status sftpProtocol::sftpGet( const KURL& src, TDEIO::filesize_t offset, int fd ) -{ - int code; - sftpFileAttr attr(remoteEncoding()); - - Status res; - res.code = 0; - res.size = 0; - - kdDebug(KIO_SFTP_DB) << "sftpGet(): " << src << endl; - - // stat the file first to get its size - if( (code = sftpStat(src, attr)) != SSH2_FX_OK ) { - return doProcessStatus(code, src.prettyURL()); - } - - // We cannot get file if it is a directory - if( attr.fileType() == S_IFDIR ) { - res.text = src.prettyURL(); - res.code = ERR_IS_DIRECTORY; - return res; - } - - TDEIO::filesize_t fileSize = attr.fileSize(); - TQ_UINT32 pflags = SSH2_FXF_READ; - attr.clear(); - - TQByteArray handle; - if( (code = sftpOpen(src, pflags, attr, handle)) != SSH2_FX_OK ) { - res.text = src.prettyURL(); - res.code = ERR_CANNOT_OPEN_FOR_READING; - return res; - } - - // needed for determining mimetype - // note: have to emit mimetype before emitting totalsize. - TQByteArray buff; - TQByteArray mimeBuffer; - - unsigned int oldSize; - bool foundMimetype = false; - - // How big should each data packet be? Definitely not bigger than 64kb or - // you will overflow the 2 byte size variable in a sftp packet. - TQ_UINT32 len = 60*1024; - code = SSH2_FX_OK; - - kdDebug(KIO_SFTP_DB) << "sftpGet(): offset = " << offset << endl; - while( code == SSH2_FX_OK ) { - if( (code = sftpRead(handle, offset, len, buff)) == SSH2_FX_OK ) { - offset += buff.size(); - - // save data for mimetype. Pretty much follows what is in the ftp ioslave - if( !foundMimetype ) { - oldSize = mimeBuffer.size(); - mimeBuffer.resize(oldSize + buff.size()); - memcpy(mimeBuffer.data()+oldSize, buff.data(), buff.size()); - - if( mimeBuffer.size() > 1024 || offset == fileSize ) { - // determine mimetype - KMimeMagicResult* result = - KMimeMagic::self()->findBufferFileType(mimeBuffer, src.fileName()); - kdDebug(KIO_SFTP_DB) << "sftpGet(): mimetype is " << - result->mimeType() << endl; - mimeType(result->mimeType()); - - // Always send the total size after emitting mime-type... - totalSize(fileSize); - - if (fd == -1) - data(mimeBuffer); - else - { - if ( (res.code=writeToFile(fd, mimeBuffer.data(), mimeBuffer.size())) != 0 ) - return res; - } - - processedSize(mimeBuffer.size()); - mimeBuffer.resize(0); - foundMimetype = true; - } - } - else { - if (fd == -1) - data(buff); - else - { - if ( (res.code= writeToFile(fd, buff.data(), buff.size())) != 0 ) - return res; - } - processedSize(offset); - } - } - - /* - Check if slave was killed. According to slavebase.h we need to leave - the slave methods as soon as possible if the slave is killed. This - allows the slave to be cleaned up properly. - */ - if( wasKilled() ) { - res.text = i18n("An internal error occurred. Please retry the request again."); - res.code = ERR_UNKNOWN; - return res; - } - } - - if( code != SSH2_FX_EOF ) { - res.text = src.prettyURL(); - res.code = ERR_COULD_NOT_READ; // return here or still send empty array to indicate end of read? - } - - res.size = offset; - sftpClose(handle); - processedSize (offset); - return res; -} - -void sftpProtocol::get(const KURL& url) { - kdDebug(KIO_SFTP_DB) << "get(): " << url << endl ; - - openConnection(); - if( !mConnected ) - return; - - // Get resume offset - TQ_UINT64 offset = config()->readUnsignedLongNumEntry("resume"); - if( offset > 0 ) { - canResume(); - kdDebug(KIO_SFTP_DB) << "get(): canResume(), offset = " << offset << endl; - } - - Status info = sftpGet(url, offset); - - if (info.code != 0) - { - error(info.code, info.text); - return; - } - - data(TQByteArray()); - kdDebug(KIO_SFTP_DB) << "get(): emit finished()" << endl; - finished(); -} - - -void sftpProtocol::setHost (const TQString& h, int port, const TQString& user, const TQString& pass) -{ - kdDebug(KIO_SFTP_DB) << "setHost(): " << user << "@" << h << ":" << port << endl; - - if( mHost != h || mPort != port || user != mUsername || mPassword != pass ) - closeConnection(); - - mHost = h; - - if( port > 0 ) - mPort = port; - else { - mPort = -1; - } - - mUsername = user; - mPassword = pass; - - if (user.isEmpty()) - { - KUser u; - mUsername = u.loginName(); - } -} - - -void sftpProtocol::openConnection() { - - if(mConnected) - return; - - kdDebug(KIO_SFTP_DB) << "openConnection(): " << mUsername << "@" - << mHost << ":" << mPort << endl; - - infoMessage( i18n("Opening SFTP connection to host %1:%2").arg(mHost).arg(mPort)); - - if( mHost.isEmpty() ) { - kdDebug(KIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; - error(ERR_UNKNOWN_HOST, i18n("No hostname specified")); - return; - } - - //////////////////////////////////////////////////////////////////////////// - // Setup AuthInfo for use with password caching and the - // password dialog box. - AuthInfo info; - info.url.setProtocol("sftp"); - info.url.setHost(mHost); - info.url.setPort(mPort); - info.url.setUser(mUsername); - info.caption = i18n("SFTP Login"); - info.comment = "sftp://" + mHost + ":" + TQString::number(mPort); - info.commentLabel = i18n("site:"); - info.username = mUsername; - info.keepPassword = true; - - /////////////////////////////////////////////////////////////////////////// - // Check for cached authentication info if a username AND password were - // not specified in setHost(). - if( mUsername.isEmpty() && mPassword.isEmpty() ) { - kdDebug(KIO_SFTP_DB) << "openConnection(): checking cache " - << "info.username = " << info.username - << ", info.url = " << info.url.prettyURL() << endl; - - if( checkCachedAuthentication(info) ) { - mUsername = info.username; - mPassword = info.password; - } - } - - /////////////////////////////////////////////////////////////////////////// - // Now setup our ssh options. If we found a cached username - // and password we set the SSH_PASSWORD and SSH_USERNAME - // options right away. Otherwise we wait. The other options are - // necessary for running sftp over ssh. - KSshProcess::SshOpt opt; // a ssh option, this can be reused - KSshProcess::SshOptList opts; // list of SshOpts - KSshProcess::SshOptListIterator passwdIt; // points to the opt in opts that specifies the password - KSshProcess::SshOptListIterator usernameIt; - -// opt.opt = KSshProcess::SSH_VERBOSE; -// opts.append(opt); -// opts.append(opt); - - if( mPort != -1 ) { - opt.opt = KSshProcess::SSH_PORT; - opt.num = mPort; - opts.append(opt); - } - - opt.opt = KSshProcess::SSH_SUBSYSTEM; - opt.str = "sftp"; - opts.append(opt); - - opt.opt = KSshProcess::SSH_FORWARDX11; - opt.boolean = false; - opts.append(opt); - - opt.opt = KSshProcess::SSH_FORWARDAGENT; - opt.boolean = false; - opts.append(opt); - - opt.opt = KSshProcess::SSH_PROTOCOL; - opt.num = 2; - opts.append(opt); - - opt.opt = KSshProcess::SSH_HOST; - opt.str = mHost; - opts.append(opt); - - opt.opt = KSshProcess::SSH_ESCAPE_CHAR; - opt.num = -1; // don't use any escape character - opts.append(opt); - - // set the username and password if we have them - if( !mUsername.isEmpty() ) { - opt.opt = KSshProcess::SSH_USERNAME; - opt.str = mUsername; - usernameIt = opts.append(opt); - } - - if( !mPassword.isEmpty() ) { - opt.opt = KSshProcess::SSH_PASSWD; - opt.str = mPassword; - passwdIt = opts.append(opt); - } - - ssh.setOptions(opts); - ssh.printArgs(); - - /////////////////////////////////////////////////////////////////////////// - // Start the ssh connection process. - // - - int err; // error code from KSshProcess - TQString msg; // msg for dialog box - TQString caption; // dialog box caption - bool firstTime = true; - bool dlgResult; - - while( !(mConnected = ssh.connect()) ) { - err = ssh.error(); - kdDebug(KIO_SFTP_DB) << "openConnection(): " - "Got " << err << " from KSshProcess::connect()" << endl; - - switch(err) { - case KSshProcess::ERR_NEED_PASSWD: - case KSshProcess::ERR_NEED_PASSPHRASE: - // At this point we know that either we didn't set - // an username or password in the ssh options list, - // or what we did pass did not work. Therefore we - // must prompt the user. - if( err == KSshProcess::ERR_NEED_PASSPHRASE ) - info.prompt = i18n("Please enter your username and key passphrase."); - else - info.prompt = i18n("Please enter your username and password."); - - kdDebug(KIO_SFTP_DB) << "openConnection(): info.username = " << info.username - << ", info.url = " << info.url.prettyURL() << endl; - - if( firstTime ) - dlgResult = openPassDlg(info); - else - dlgResult = openPassDlg(info, i18n("Incorrect username or password")); - - if( dlgResult ) { - if( info.username.isEmpty() || info.password.isEmpty() ) { - error(ERR_COULD_NOT_AUTHENTICATE, - i18n("Please enter a username and password")); - continue; - } - } - else { - // user canceled or dialog failed to open - error(ERR_USER_CANCELED, TQString::null); - kdDebug(KIO_SFTP_DB) << "openConnection(): user canceled, dlgResult = " << dlgResult << endl; - closeConnection(); - return; - } - - firstTime = false; - - // Check if the username has changed. SSH only accepts - // the username at startup. If the username has changed - // we must disconnect ssh, change the SSH_USERNAME - // option, and reset the option list. We will also set - // the password option so the user is not prompted for - // it again. - if( mUsername != info.username ) { - kdDebug(KIO_SFTP_DB) << "openConnection(): Username changed from " - << mUsername << " to " << info.username << endl; - - ssh.disconnect(); - - // if we haven't yet added the username - // or password option to the ssh options list then - // the iterators will be equal to the empty iterator. - // Create the opts now and add them to the opt list. - if( usernameIt == KSshProcess::SshOptListIterator() ) { - kdDebug(KIO_SFTP_DB) << "openConnection(): " - "Adding username to options list" << endl; - opt.opt = KSshProcess::SSH_USERNAME; - usernameIt = opts.append(opt); - } - - if( passwdIt == KSshProcess::SshOptListIterator() ) { - kdDebug(KIO_SFTP_DB) << "openConnection(): " - "Adding password to options list" << endl; - opt.opt = KSshProcess::SSH_PASSWD; - passwdIt = opts.append(opt); - } - - (*usernameIt).str = info.username; - (*passwdIt).str = info.password; - ssh.setOptions(opts); - ssh.printArgs(); - } - else { // just set the password - ssh.setPassword(info.password); - } - - mUsername = info.username; - mPassword = info.password; - - break; - - case KSshProcess::ERR_NEW_HOST_KEY: - caption = i18n("Warning: Cannot verify host's identity."); - msg = ssh.errorMsg(); - if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { - closeConnection(); - error(ERR_USER_CANCELED, TQString::null); - return; - } - ssh.acceptHostKey(true); - break; - - case KSshProcess::ERR_DIFF_HOST_KEY: - caption = i18n("Warning: Host's identity changed."); - msg = ssh.errorMsg(); - if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { - closeConnection(); - error(ERR_USER_CANCELED, TQString::null); - return; - } - ssh.acceptHostKey(true); - break; - - case KSshProcess::ERR_AUTH_FAILED: - infoMessage(i18n("Authentication failed.")); - error(ERR_COULD_NOT_LOGIN, i18n("Authentication failed.")); - return; - - case KSshProcess::ERR_AUTH_FAILED_NEW_KEY: - msg = ssh.errorMsg(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_AUTH_FAILED_DIFF_KEY: - msg = ssh.errorMsg(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_CLOSED_BY_REMOTE_HOST: - infoMessage(i18n("Connection failed.")); - caption = i18n("Connection closed by remote host."); - msg = ssh.errorMsg(); - messageBox(Information, msg, caption); - closeConnection(); - error(ERR_COULD_NOT_LOGIN, msg); - return; - - case KSshProcess::ERR_INTERACT: - case KSshProcess::ERR_INTERNAL: - case KSshProcess::ERR_UNKNOWN: - case KSshProcess::ERR_INVALID_STATE: - case KSshProcess::ERR_CANNOT_LAUNCH: - case KSshProcess::ERR_HOST_KEY_REJECTED: - default: - infoMessage(i18n("Connection failed.")); - caption = i18n("Unexpected SFTP error: %1").arg(err); - msg = ssh.errorMsg(); - messageBox(Information, msg, caption); - closeConnection(); - error(ERR_UNKNOWN, msg); - return; - } - } - - // catch all in case we did something wrong above - if( !mConnected ) { - error(ERR_INTERNAL, TQString::null); - return; - } - - // Now send init packet. - kdDebug(KIO_SFTP_DB) << "openConnection(): Sending SSH2_FXP_INIT packet." << endl; - TQByteArray p; - TQDataStream packet(p, IO_WriteOnly); - packet << (TQ_UINT32)5; // packet length - packet << (TQ_UINT8) SSH2_FXP_INIT; // packet type - packet << (TQ_UINT32)SSH2_FILEXFER_VERSION; // client version - - putPacket(p); - getPacket(p); - - TQDataStream s(p, IO_ReadOnly); - TQ_UINT32 version; - TQ_UINT8 type; - s >> type; - kdDebug(KIO_SFTP_DB) << "openConnection(): Got type " << type << endl; - - if( type == SSH2_FXP_VERSION ) { - s >> version; - kdDebug(KIO_SFTP_DB) << "openConnection(): Got server version " << version << endl; - - // XXX Get extensions here - sftpVersion = version; - - /* Server should return lowest common version supported by - * client and server, but double check just in case. - */ - if( sftpVersion > SSH2_FILEXFER_VERSION ) { - error(ERR_UNSUPPORTED_PROTOCOL, - i18n("SFTP version %1").arg(version)); - closeConnection(); - return; - } - } - else { - error(ERR_UNKNOWN, i18n("Protocol error.")); - closeConnection(); - return; - } - - // Login succeeded! - infoMessage(i18n("Successfully connected to %1").arg(mHost)); - info.url.setProtocol("sftp"); - info.url.setHost(mHost); - info.url.setPort(mPort); - info.url.setUser(mUsername); - info.username = mUsername; - info.password = mPassword; - kdDebug(KIO_SFTP_DB) << "sftpProtocol(): caching info.username = " << info.username << - ", info.url = " << info.url.prettyURL() << endl; - cacheAuthentication(info); - mConnected = true; - connected(); - - mPassword.fill('x'); - info.password.fill('x'); - - return; -} - -void sftpProtocol::closeConnection() { - kdDebug(KIO_SFTP_DB) << "closeConnection()" << endl; - ssh.disconnect(); - mConnected = false; -} - -void sftpProtocol::sftpCopyPut(const KURL& src, const KURL& dest, int permissions, bool overwrite) { - - KDE_struct_stat buff; - TQCString file (TQFile::encodeName(src.path())); - - if (KDE_lstat(file.data(), &buff) == -1) { - error (ERR_DOES_NOT_EXIST, src.prettyURL()); - return; - } - - if (S_ISDIR (buff.st_mode)) { - error (ERR_IS_DIRECTORY, src.prettyURL()); - return; - } - - int fd = KDE_open (file.data(), O_RDONLY); - if (fd == -1) { - error (ERR_CANNOT_OPEN_FOR_READING, src.prettyURL()); - return; - } - - totalSize (buff.st_size); - - sftpPut (dest, permissions, false, overwrite, fd); - - // Close the file descriptor... - ::close( fd ); -} - -void sftpProtocol::sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd ) { - - openConnection(); - if( !mConnected ) - return; - - kdDebug(KIO_SFTP_DB) << "sftpPut(): " << dest - << ", resume=" << resume - << ", overwrite=" << overwrite << endl; - - KURL origUrl( dest ); - sftpFileAttr origAttr(remoteEncoding()); - bool origExists = false; - - // Stat original (without part ext) to see if it already exists - int code = sftpStat(origUrl, origAttr); - - if( code == SSH2_FX_OK ) { - kdDebug(KIO_SFTP_DB) << "sftpPut(): already exists" << endl; - - // Delete remote file if its size is zero - if( origAttr.fileSize() == 0 ) { - if( sftpRemove(origUrl, true) != SSH2_FX_OK ) { - error(ERR_CANNOT_DELETE_ORIGINAL, origUrl.prettyURL()); - return; - } - } - else { - origExists = true; - } - } - else if( code != SSH2_FX_NO_SUCH_FILE ) { - processStatus(code, origUrl.prettyURL()); - return; - } - - // Do not waste time/resources with more remote stat calls if the file exists - // and we weren't instructed to overwrite it... - if( origExists && !overwrite ) { - error(ERR_FILE_ALREADY_EXIST, origUrl.prettyURL()); - return; - } - - // Stat file with part ext to see if it already exists... - KURL partUrl( origUrl ); - partUrl.setFileName( partUrl.fileName() + ".part" ); - - TQ_UINT64 offset = 0; - bool partExists = false; - bool markPartial = config()->readBoolEntry("MarkPartial", true); - - if( markPartial ) { - - sftpFileAttr partAttr(remoteEncoding()); - code = sftpStat(partUrl, partAttr); - - if( code == SSH2_FX_OK ) { - kdDebug(KIO_SFTP_DB) << "sftpPut(): .part file already exists" << endl; - partExists = true; - offset = partAttr.fileSize(); - - // If for some reason, both the original and partial files exist, - // skip resumption just like we would if the size of the partial - // file is zero... - if( origExists || offset == 0 ) - { - if( sftpRemove(partUrl, true) != SSH2_FX_OK ) { - error(ERR_CANNOT_DELETE_PARTIAL, partUrl.prettyURL()); - return; - } - - if( sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); - return; - } - - offset = 0; - } - else if( !overwrite && !resume ) { - if (fd != -1) - resume = (KDE_lseek(fd, offset, SEEK_SET) != -1); - else - resume = canResume( offset ); - - kdDebug(KIO_SFTP_DB) << "sftpPut(): can resume = " << resume - << ", offset = " << offset; - - if( !resume ) { - error(ERR_FILE_ALREADY_EXIST, partUrl.prettyURL()); - return; - } - } - else { - offset = 0; - } - } - else if( code == SSH2_FX_NO_SUCH_FILE ) { - if( origExists && sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); - return; - } - } - else { - processStatus(code, partUrl.prettyURL()); - return; - } - } - - // Determine the url we will actually write to... - KURL writeUrl (markPartial ? partUrl:origUrl); - - TQ_UINT32 pflags = 0; - if( overwrite && !resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_TRUNC; - else if( !overwrite && !resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_EXCL; - else if( overwrite && resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT; - else if( !overwrite && resume ) - pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_APPEND; - - sftpFileAttr attr(remoteEncoding()); - TQByteArray handle; - - // Set the permissions of the file we write to if it didn't already exist - // and the permission info is supplied, i.e it is not -1 - if( !partExists && !origExists && permissions != -1) - attr.setPermissions(permissions); - - code = sftpOpen( writeUrl, pflags, attr, handle ); - if( code != SSH2_FX_OK ) { - - // Rename the file back to its original name if a - // put fails due to permissions problems... - if( markPartial && overwrite ) { - (void) sftpRename(partUrl, origUrl); - writeUrl = origUrl; - } - - if( code == SSH2_FX_FAILURE ) { // assume failure means file exists - error(ERR_FILE_ALREADY_EXIST, writeUrl.prettyURL()); - return; - } - else { - processStatus(code, writeUrl.prettyURL()); - return; - } - } - - long nbytes; - TQByteArray buff; - - do { - - if( fd != -1 ) { - buff.resize( 16*1024 ); - if ( (nbytes = ::read(fd, buff.data(), buff.size())) > -1 ) - buff.resize( nbytes ); - } - else { - dataReq(); - nbytes = readData( buff ); - } - - if( nbytes >= 0 ) { - if( (code = sftpWrite(handle, offset, buff)) != SSH2_FX_OK ) { - error(ERR_COULD_NOT_WRITE, dest.prettyURL()); - return; - } - - offset += nbytes; - processedSize(offset); - - /* Check if slave was killed. According to slavebase.h we - * need to leave the slave methods as soon as possible if - * the slave is killed. This allows the slave to be cleaned - * up properly. - */ - if( wasKilled() ) { - sftpClose(handle); - closeConnection(); - error(ERR_UNKNOWN, i18n("An internal error occurred. Please try again.")); - return; - } - } - - } while( nbytes > 0 ); - - if( nbytes < 0 ) { - sftpClose(handle); - - if( markPartial ) { - // Remove remote file if it smaller than our keep size - uint minKeepSize = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); - - if( sftpStat(writeUrl, attr) == SSH2_FX_OK ) { - if( attr.fileSize() < minKeepSize ) { - sftpRemove(writeUrl, true); - } - } - } - - error( ERR_UNKNOWN, i18n("Unknown error was encountered while copying the file " - "to '%1'. Please try again.").arg(dest.host()) ); - return; - } - - if( (code = sftpClose(handle)) != SSH2_FX_OK ) { - error(ERR_COULD_NOT_WRITE, writeUrl.prettyURL()); - return; - } - - // If wrote to a partial file, then remove the part ext - if( markPartial ) { - if( sftpRename(partUrl, origUrl) != SSH2_FX_OK ) { - error(ERR_CANNOT_RENAME_PARTIAL, origUrl.prettyURL()); - return; - } - } - - finished(); -} - -void sftpProtocol::put ( const KURL& url, int permissions, bool overwrite, bool resume ){ - kdDebug(KIO_SFTP_DB) << "put(): " << url << ", overwrite = " << overwrite - << ", resume = " << resume << endl; - - sftpPut( url, permissions, resume, overwrite ); -} - -void sftpProtocol::stat ( const KURL& url ){ - kdDebug(KIO_SFTP_DB) << "stat(): " << url << endl; - - openConnection(); - if( !mConnected ) - return; - - // If the stat URL has no path, do not attempt to determine the real - // path and do a redirect. KRun will simply ignore such requests. - // Instead, simply return the mime-type as a directory... - if( !url.hasPath() ) { - UDSEntry entry; - UDSAtom atom; - - atom.m_uds = TDEIO::UDS_NAME; - atom.m_str = TQString::null; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - entry.append( atom ); - - atom.m_uds = TDEIO::UDS_USER; - atom.m_str = mUsername; - entry.append( atom ); - atom.m_uds = TDEIO::UDS_GROUP; - entry.append( atom ); - - // no size - statEntry( entry ); - finished(); - return; - } - - int code; - sftpFileAttr attr(remoteEncoding()); - if( (code = sftpStat(url, attr)) != SSH2_FX_OK ) { - processStatus(code, url.prettyURL()); - return; - } - else { - //kdDebug() << "We sent and received stat packet ok" << endl; - attr.setFilename(url.fileName()); - statEntry(attr.entry()); - } - - finished(); - - kdDebug(KIO_SFTP_DB) << "stat: END" << endl; - return; -} - - -void sftpProtocol::mimetype ( const KURL& url ){ - kdDebug(KIO_SFTP_DB) << "mimetype(): " << url << endl; - - openConnection(); - if( !mConnected ) - return; - - TQ_UINT32 pflags = SSH2_FXF_READ; - TQByteArray handle, mydata; - sftpFileAttr attr(remoteEncoding()); - int code; - if( (code = sftpOpen(url, pflags, attr, handle)) != SSH2_FX_OK ) { - error(ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); - return; - } - - TQ_UINT32 len = 1024; // Get first 1k for determining mimetype - TQ_UINT64 offset = 0; - code = SSH2_FX_OK; - while( offset < len && code == SSH2_FX_OK ) { - if( (code = sftpRead(handle, offset, len, mydata)) == SSH2_FX_OK ) { - data(mydata); - offset += mydata.size(); - processedSize(offset); - - kdDebug(KIO_SFTP_DB) << "mimetype(): offset = " << offset << endl; - } - } - - - data(TQByteArray()); - processedSize(offset); - sftpClose(handle); - finished(); - kdDebug(KIO_SFTP_DB) << "mimetype(): END" << endl; -} - - -void sftpProtocol::listDir(const KURL& url) { - kdDebug(KIO_SFTP_DB) << "listDir(): " << url << endl; - - openConnection(); - if( !mConnected ) - return; - - if( !url.hasPath() ) { - KURL newUrl ( url ); - if( sftpRealPath(url, newUrl) == SSH2_FX_OK ) { - kdDebug(KIO_SFTP_DB) << "listDir: Redirecting to " << newUrl << endl; - redirection(newUrl); - finished(); - return; - } - } - - int code; - TQByteArray handle; - - if( (code = sftpOpenDirectory(url, handle)) != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "listDir(): open directory failed" << endl; - processStatus(code, url.prettyURL()); - return; - } - - - code = SSH2_FX_OK; - while( code == SSH2_FX_OK ) { - code = sftpReadDir(handle, url); - if( code != SSH2_FX_OK && code != SSH2_FX_EOF ) - processStatus(code, url.prettyURL()); - kdDebug(KIO_SFTP_DB) << "listDir(): return code = " << code << endl; - } - - if( (code = sftpClose(handle)) != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "listdir(): closing of directory failed" << endl; - processStatus(code, url.prettyURL()); - return; - } - - finished(); - kdDebug(KIO_SFTP_DB) << "listDir(): END" << endl; -} - -/** Make a directory. - OpenSSH does not follow the internet draft for sftp in this case. - The format of the mkdir request expected by OpenSSH sftp server is: - uint32 id - string path - ATTR attr - */ -void sftpProtocol::mkdir(const KURL&url, int permissions){ - - kdDebug(KIO_SFTP_DB) << "mkdir() creating dir: " << url.path() << endl; - - openConnection(); - if( !mConnected ) - return; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - sftpFileAttr attr(remoteEncoding()); - - if (permissions != -1) - attr.setPermissions(permissions); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); - s << (TQ_UINT8)SSH2_FXP_MKDIR; - s << id; - s.writeBytes(path.data(), len); - s << attr; - - kdDebug(KIO_SFTP_DB) << "mkdir(): packet size is " << p.size() << endl; - - putPacket(p); - getPacket(p); - - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "mkdir: sftp packet id mismatch" << endl; - error(ERR_COULD_NOT_MKDIR, path); - finished(); - return; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "mkdir(): unexpected packet type of " << type << endl; - error(ERR_COULD_NOT_MKDIR, path); - finished(); - return; - } - - int code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "mkdir(): failed with code " << code << endl; - - // Check if mkdir failed because the directory already exists so that - // we can return the appropriate message... - sftpFileAttr dirAttr(remoteEncoding()); - if ( sftpStat(url, dirAttr) == SSH2_FX_OK ) - { - error( ERR_DIR_ALREADY_EXIST, url.prettyURL() ); - return; - } - - error(ERR_COULD_NOT_MKDIR, path); - } - - finished(); -} - -void sftpProtocol::rename(const KURL& src, const KURL& dest, bool overwrite){ - kdDebug(KIO_SFTP_DB) << "rename(" << src << " -> " << dest << ")" << endl; - - if (!isSupportedOperation(SSH2_FXP_RENAME)) { - error(ERR_UNSUPPORTED_ACTION, - i18n("The remote host does not support renaming files.")); - return; - } - - openConnection(); - if( !mConnected ) - return; - - // Always stat the destination before attempting to rename - // a file or a directory... - sftpFileAttr attr(remoteEncoding()); - int code = sftpStat(dest, attr); - - // If the destination directory, exists tell it to the job - // so it the proper action can be presented to the user... - if( code == SSH2_FX_OK ) - { - if (!overwrite) - { - if ( S_ISDIR(attr.permissions()) ) - error( TDEIO::ERR_DIR_ALREADY_EXIST, dest.url() ); - else - error( TDEIO::ERR_FILE_ALREADY_EXIST, dest.url() ); - return; - } - - // If overwrite is specified, then simply remove the existing file/dir first... - if( (code = sftpRemove( dest, !S_ISDIR(attr.permissions()) )) != SSH2_FX_OK ) - { - processStatus(code); - return; - } - } - - // Do the renaming... - if( (code = sftpRename(src, dest)) != SSH2_FX_OK ) { - processStatus(code); - return; - } - - finished(); - kdDebug(KIO_SFTP_DB) << "rename(): END" << endl; -} - -void sftpProtocol::symlink(const TQString& target, const KURL& dest, bool overwrite){ - kdDebug(KIO_SFTP_DB) << "symlink()" << endl; - - if (!isSupportedOperation(SSH2_FXP_SYMLINK)) { - error(ERR_UNSUPPORTED_ACTION, - i18n("The remote host does not support creating symbolic links.")); - return; - } - - openConnection(); - if( !mConnected ) - return; - - int code; - bool failed = false; - if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) { - if( overwrite ) { // try to delete the destination - sftpFileAttr attr(remoteEncoding()); - if( (code = sftpStat(dest, attr)) != SSH2_FX_OK ) { - failed = true; - } - else { - if( (code = sftpRemove(dest, !S_ISDIR(attr.permissions())) ) != SSH2_FX_OK ) { - failed = true; - } - else { - // XXX what if rename fails again? We have lost the file. - // Maybe rename dest to a temporary name first? If rename is - // successful, then delete? - if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) - failed = true; - } - } - } - else if( code == SSH2_FX_FAILURE ) { - error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); - return; - } - else - failed = true; - } - - // What error code do we return? Code for the original symlink command - // or for the last command or for both? The second one is implemented here. - if( failed ) - processStatus(code); - - finished(); -} - -void sftpProtocol::chmod(const KURL& url, int permissions){ - TQString perms; - perms.setNum(permissions, 8); - kdDebug(KIO_SFTP_DB) << "chmod(" << url << ", " << perms << ")" << endl; - - openConnection(); - if( !mConnected ) - return; - - sftpFileAttr attr(remoteEncoding()); - - if (permissions != -1) - attr.setPermissions(permissions); - - int code; - if( (code = sftpSetStat(url, attr)) != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "chmod(): sftpSetStat failed with error " << code << endl; - if( code == SSH2_FX_FAILURE ) - error(ERR_CANNOT_CHMOD, TQString::null); - else - processStatus(code, url.prettyURL()); - } - finished(); -} - - -void sftpProtocol::del(const KURL &url, bool isfile){ - kdDebug(KIO_SFTP_DB) << "del(" << url << ", " << (isfile?"file":"dir") << ")" << endl; - - openConnection(); - if( !mConnected ) - return; - - int code; - if( (code = sftpRemove(url, isfile)) != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "del(): sftpRemove failed with error code " << code << endl; - processStatus(code, url.prettyURL()); - } - finished(); -} - -void sftpProtocol::slave_status() { - kdDebug(KIO_SFTP_DB) << "slave_status(): connected to " - << mHost << "? " << mConnected << endl; - - slaveStatus ((mConnected ? mHost : TQString::null), mConnected); -} - -bool sftpProtocol::getPacket(TQByteArray& msg) { - TQByteArray buf(4096); - - // Get the message length... - ssize_t len = atomicio(ssh.stdioFd(), buf.data(), 4, true /*read*/); - - if( len == 0 || len == -1 ) { - kdDebug(KIO_SFTP_DB) << "getPacket(): read of packet length failed, ret = " - << len << ", error =" << strerror(errno) << endl; - closeConnection(); - error( ERR_CONNECTION_BROKEN, mHost); - msg.resize(0); - return false; - } - - uint msgLen; - TQDataStream s(buf, IO_ReadOnly); - s >> msgLen; - - //kdDebug(KIO_SFTP_DB) << "getPacket(): Message size = " << msgLen << endl; - - msg.resize(0); - - TQBuffer b( msg ); - b.open( IO_WriteOnly ); - - while( msgLen ) { - len = atomicio(ssh.stdioFd(), buf.data(), kMin((uint)buf.size(), msgLen), true /*read*/); - - if( len == 0 || len == -1) { - TQString errmsg; - if (len == 0) - errmsg = i18n("Connection closed"); - else - errmsg = i18n("Could not read SFTP packet"); - kdDebug(KIO_SFTP_DB) << "getPacket(): nothing to read, ret = " << - len << ", error =" << strerror(errno) << endl; - closeConnection(); - error(ERR_CONNECTION_BROKEN, errmsg); - b.close(); - return false; - } - - b.writeBlock(buf.data(), len); - - //kdDebug(KIO_SFTP_DB) << "getPacket(): Read Message size = " << len << endl; - //kdDebug(KIO_SFTP_DB) << "getPacket(): Copy Message size = " << msg.size() << endl; - - msgLen -= len; - } - - b.close(); - - return true; -} - -/** Send an sftp packet to stdin of the ssh process. */ -bool sftpProtocol::putPacket(TQByteArray& p){ -// kdDebug(KIO_SFTP_DB) << "putPacket(): size == " << p.size() << endl; - int ret; - ret = atomicio(ssh.stdioFd(), p.data(), p.size(), false /*write*/); - if( ret <= 0 ) { - kdDebug(KIO_SFTP_DB) << "putPacket(): write failed, ret =" << ret << - ", error = " << strerror(errno) << endl; - return false; - } - - return true; -} - -/** Used to have the server canonicalize any given path name to an absolute path. -This is useful for converting path names containing ".." components or relative -pathnames without a leading slash into absolute paths. -Returns the canonicalized url. */ -int sftpProtocol::sftpRealPath(const KURL& url, KURL& newUrl){ - - kdDebug(KIO_SFTP_DB) << "sftpRealPath(" << url << ", newUrl)" << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_REALPATH; - s << id; - s.writeBytes(path.data(), len); - - putPacket(p); - getPacket(p); - - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpRealPath: sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 code; - r >> code; - return code; - } - - if( type != SSH2_FXP_NAME ) { - kdError(KIO_SFTP_DB) << "sftpRealPath(): unexpected packet type of " << type << endl; - return -1; - } - - TQ_UINT32 count; - r >> count; - if( count != 1 ) { - kdError(KIO_SFTP_DB) << "sftpRealPath(): Bad number of file attributes for realpath command" << endl; - return -1; - } - - TQCString newPath; - r >> newPath; - - newPath.truncate(newPath.size()); - if (newPath.isEmpty()) - newPath = "/"; - newUrl.setPath(newPath); - - return SSH2_FX_OK; -} - -sftpProtocol::Status sftpProtocol::doProcessStatus(TQ_UINT8 code, const TQString& message) -{ - Status res; - res.code = 0; - res.size = 0; - res.text = message; - - switch(code) - { - case SSH2_FX_OK: - case SSH2_FX_EOF: - break; - case SSH2_FX_NO_SUCH_FILE: - res.code = ERR_DOES_NOT_EXIST; - break; - case SSH2_FX_PERMISSION_DENIED: - res.code = ERR_ACCESS_DENIED; - break; - case SSH2_FX_FAILURE: - res.text = i18n("SFTP command failed for an unknown reason."); - res.code = ERR_UNKNOWN; - break; - case SSH2_FX_BAD_MESSAGE: - res.text = i18n("The SFTP server received a bad message."); - res.code = ERR_UNKNOWN; - break; - case SSH2_FX_OP_UNSUPPORTED: - res.text = i18n("You attempted an operation unsupported by the SFTP server."); - res.code = ERR_UNKNOWN; - break; - default: - res.text = i18n("Error code: %1").arg(code); - res.code = ERR_UNKNOWN; - } - - return res; -} - -/** Process SSH_FXP_STATUS packets. */ -void sftpProtocol::processStatus(TQ_UINT8 code, const TQString& message){ - Status st = doProcessStatus( code, message ); - if( st.code != 0 ) - error( st.code, st.text ); -} - -/** Opens a directory handle for url.path. Returns true if succeeds. */ -int sftpProtocol::sftpOpenDirectory(const KURL& url, TQByteArray& handle){ - - kdDebug(KIO_SFTP_DB) << "sftpOpenDirectory(" << url << ", handle)" << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_OPENDIR; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpOpenDirectory: sftp packet id mismatch: " << - "expected " << expectedId << ", got " << id << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - return errCode; - } - - if( type != SSH2_FXP_HANDLE ) { - kdError(KIO_SFTP_DB) << "sftpOpenDirectory: unexpected message type of " << type << endl; - return -1; - } - - r >> handle; - if( handle.size() > 256 ) { - kdError(KIO_SFTP_DB) << "sftpOpenDirectory: handle exceeds max length" << endl; - return -1; - } - - kdDebug(KIO_SFTP_DB) << "sftpOpenDirectory: handle (" << handle.size() << "): [" << handle << "]" << endl; - return SSH2_FX_OK; -} - -/** Closes a directory or file handle. */ -int sftpProtocol::sftpClose(const TQByteArray& handle){ - - kdDebug(KIO_SFTP_DB) << "sftpClose()" << endl; - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); - s << (TQ_UINT8)SSH2_FXP_CLOSE; - s << (TQ_UINT32)id; - s << handle; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpClose: sftp packet id mismatch" << endl; - return -1; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "sftpClose: unexpected message type of " << type << endl; - return -1; - } - - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "sftpClose: close failed with err code " << code << endl; - } - - return code; -} - -/** Set a files attributes. */ -int sftpProtocol::sftpSetStat(const KURL& url, const sftpFileAttr& attr){ - - kdDebug(KIO_SFTP_DB) << "sftpSetStat(" << url << ", attr)" << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); - s << (TQ_UINT8)SSH2_FXP_SETSTAT; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - s << attr; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpSetStat(): sftp packet id mismatch" << endl; - return -1; - // XXX How do we do a fatal error? - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "sftpSetStat(): unexpected message type of " << type << endl; - return -1; - } - - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "sftpSetStat(): set stat failed with err code " << code << endl; - } - - return code; -} - -/** Sends a sftp command to remove a file or directory. */ -int sftpProtocol::sftpRemove(const KURL& url, bool isfile){ - - kdDebug(KIO_SFTP_DB) << "sftpRemove(): " << url << ", isFile ? " << isfile << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)(isfile ? SSH2_FXP_REMOVE : SSH2_FXP_RMDIR); - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "del(): sftp packet id mismatch" << endl; - return -1; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "del(): unexpected message type of " << type << endl; - return -1; - } - - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "del(): del failed with err code " << code << endl; - } - - return code; -} - -/** Send a sftp command to rename a file or directoy. */ -int sftpProtocol::sftpRename(const KURL& src, const KURL& dest){ - - kdDebug(KIO_SFTP_DB) << "sftpRename(" << src << " -> " << dest << ")" << endl; - - TQCString srcPath = remoteEncoding()->encode(src.path()); - TQCString destPath = remoteEncoding()->encode(dest.path()); - - uint slen = srcPath.length(); - uint dlen = destPath.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + slen + - 4 /*str length*/ + dlen); - s << (TQ_UINT8)SSH2_FXP_RENAME; - s << (TQ_UINT32)id; - s.writeBytes(srcPath.data(), slen); - s.writeBytes(destPath.data(), dlen); - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpRename(): sftp packet id mismatch" << endl; - return -1; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "sftpRename(): unexpected message type of " << type << endl; - return -1; - } - - int code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "sftpRename(): rename failed with err code " << code << endl; - } - - return code; -} -/** Get directory listings. */ -int sftpProtocol::sftpReadDir(const TQByteArray& handle, const KURL& url){ - // url is needed so we can lookup the link destination - kdDebug(KIO_SFTP_DB) << "sftpReadDir(): " << url << endl; - - TQ_UINT32 id, expectedId, count; - TQ_UINT8 type; - - sftpFileAttr attr (remoteEncoding()); - attr.setDirAttrsFlag(true); - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); - s << (TQ_UINT8)SSH2_FXP_READDIR; - s << (TQ_UINT32)id; - s << handle; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - r >> type >> id; - - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpReadDir(): sftp packet id mismatch" << endl; - return -1; - } - - int code; - if( type == SSH2_FXP_STATUS ) { - r >> code; - return code; - } - - if( type != SSH2_FXP_NAME ) { - kdError(KIO_SFTP_DB) << "kio_sftpProtocl::sftpReadDir(): Unexpected message" << endl; - return -1; - } - - r >> count; - kdDebug(KIO_SFTP_DB) << "sftpReadDir(): got " << count << " entries" << endl; - - while(count--) { - r >> attr; - - if( S_ISLNK(attr.permissions()) ) { - KURL myurl ( url ); - myurl.addPath(attr.filename()); - - // Stat the symlink to find out its type... - sftpFileAttr attr2 (remoteEncoding()); - (void) sftpStat(myurl, attr2); - - attr.setLinkType(attr2.linkType()); - attr.setLinkDestination(attr2.linkDestination()); - } - - listEntry(attr.entry(), false); - } - - listEntry(attr.entry(), true); - - return SSH2_FX_OK; -} - -int sftpProtocol::sftpReadLink(const KURL& url, TQString& target){ - - kdDebug(KIO_SFTP_DB) << "sftpReadLink(): " << url << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - //kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Encoded Path: " << path << endl; - //kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Encoded Size: " << len << endl; - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_READLINK; - s << id; - s.writeBytes(path.data(), len); - - - putPacket(p); - getPacket(p); - - TQ_UINT8 type; - TQDataStream r(p, IO_ReadOnly); - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpReadLink(): sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 code; - r >> code; - kdDebug(KIO_SFTP_DB) << "sftpReadLink(): read link failed with code " << code << endl; - return code; - } - - if( type != SSH2_FXP_NAME ) { - kdError(KIO_SFTP_DB) << "sftpReadLink(): unexpected packet type of " << type << endl; - return -1; - } - - TQ_UINT32 count; - r >> count; - if( count != 1 ) { - kdError(KIO_SFTP_DB) << "sftpReadLink(): Bad number of file attributes for realpath command" << endl; - return -1; - } - - TQCString linkAddress; - r >> linkAddress; - - linkAddress.truncate(linkAddress.size()); - kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Link address: " << linkAddress << endl; - - target = remoteEncoding()->decode(linkAddress); - - return SSH2_FX_OK; -} - -int sftpProtocol::sftpSymLink(const TQString& _target, const KURL& dest){ - - TQCString destPath = remoteEncoding()->encode(dest.path()); - TQCString target = remoteEncoding()->encode(_target); - uint dlen = destPath.length(); - uint tlen = target.length(); - - kdDebug(KIO_SFTP_DB) << "sftpSymLink(" << target << " -> " << destPath << ")" << endl; - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + tlen + - 4 /*str length*/ + dlen); - s << (TQ_UINT8)SSH2_FXP_SYMLINK; - s << (TQ_UINT32)id; - s.writeBytes(target.data(), tlen); - s.writeBytes(destPath.data(), dlen); - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpSymLink(): sftp packet id mismatch" << endl; - return -1; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "sftpSymLink(): unexpected message type of " << type << endl; - return -1; - } - - TQ_UINT32 code; - r >> code; - if( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "sftpSymLink(): rename failed with err code " << code << endl; - } - - return code; -} - -/** Stats a file. */ -int sftpProtocol::sftpStat(const KURL& url, sftpFileAttr& attr) { - - kdDebug(KIO_SFTP_DB) << "sftpStat(): " << url << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); - s << (TQ_UINT8)SSH2_FXP_LSTAT; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpStat(): sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - kdError(KIO_SFTP_DB) << "sftpStat(): stat failed with code " << errCode << endl; - return errCode; - } - - if( type != SSH2_FXP_ATTRS ) { - kdError(KIO_SFTP_DB) << "sftpStat(): unexpected message type of " << type << endl; - return -1; - } - - r >> attr; - attr.setFilename(url.fileName()); - kdDebug(KIO_SFTP_DB) << "sftpStat(): " << attr << endl; - - // If the stat'ed resource is a symlink, perform a recursive stat - // to determine the actual destination's type (file/dir). - if( S_ISLNK(attr.permissions()) && isSupportedOperation(SSH2_FXP_READLINK) ) { - - TQString target; - int code = sftpReadLink( url, target ); - - if ( code != SSH2_FX_OK ) { - kdError(KIO_SFTP_DB) << "sftpStat(): Unable to stat symlink destination" << endl; - return -1; - } - - kdDebug(KIO_SFTP_DB) << "sftpStat(): Resource is a symlink to -> " << target << endl; - - KURL dest( url ); - if( target[0] == '/' ) - dest.setPath(target); - else - dest.setFileName(target); - - dest.cleanPath(); - - // Ignore symlinks that point to themselves... - if ( dest != url ) { - - sftpFileAttr attr2 (remoteEncoding()); - (void) sftpStat(dest, attr2); - - if (attr2.linkType() == 0) - attr.setLinkType(attr2.fileType()); - else - attr.setLinkType(attr2.linkType()); - - attr.setLinkDestination(target); - - kdDebug(KIO_SFTP_DB) << "sftpStat(): File type: " << attr.fileType() << endl; - } - } - - return SSH2_FX_OK; -} - - -int sftpProtocol::sftpOpen(const KURL& url, const TQ_UINT32 pflags, - const sftpFileAttr& attr, TQByteArray& handle) { - kdDebug(KIO_SFTP_DB) << "sftpOpen(" << url << ", handle" << endl; - - TQCString path = remoteEncoding()->encode(url.path()); - uint len = path.length(); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + len + - 4 /*pflags*/ + attr.size()); - s << (TQ_UINT8)SSH2_FXP_OPEN; - s << (TQ_UINT32)id; - s.writeBytes(path.data(), len); - s << pflags; - s << attr; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpOpen(): sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - return errCode; - } - - if( type != SSH2_FXP_HANDLE ) { - kdError(KIO_SFTP_DB) << "sftpOpen(): unexpected message type of " << type << endl; - return -1; - } - - r >> handle; - if( handle.size() > 256 ) { - kdError(KIO_SFTP_DB) << "sftpOpen(): handle exceeds max length" << endl; - return -1; - } - - kdDebug(KIO_SFTP_DB) << "sftpOpen(): handle (" << handle.size() << "): [" << handle << "]" << endl; - return SSH2_FX_OK; -} - - -int sftpProtocol::sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data) -{ - // kdDebug(KIO_SFTP_DB) << "sftpRead( offset = " << offset << ", len = " << len << ")" << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + handle.size() + - 8 /*offset*/ + 4 /*length*/); - s << (TQ_UINT8)SSH2_FXP_READ; - s << (TQ_UINT32)id; - s << handle; - s << offset; // we don't have a convienient 64 bit int so set upper int to zero - s << len; - - putPacket(p); - getPacket(p); - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpRead: sftp packet id mismatch" << endl; - return -1; - } - - if( type == SSH2_FXP_STATUS ) { - TQ_UINT32 errCode; - r >> errCode; - kdError(KIO_SFTP_DB) << "sftpRead: read failed with code " << errCode << endl; - return errCode; - } - - if( type != SSH2_FXP_DATA ) { - kdError(KIO_SFTP_DB) << "sftpRead: unexpected message type of " << type << endl; - return -1; - } - - r >> data; - - return SSH2_FX_OK; -} - - -int sftpProtocol::sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data){ -// kdDebug(KIO_SFTP_DB) << "sftpWrite( offset = " << offset << -// ", data sz = " << data.size() << ")" << endl; - TQByteArray p; - TQDataStream s(p, IO_WriteOnly); - - TQ_UINT32 id, expectedId; - id = expectedId = mMsgId++; - s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + - 4 /*str length*/ + handle.size() + - 8 /*offset*/ + - 4 /* data size */ + data.size()); - s << (TQ_UINT8)SSH2_FXP_WRITE; - s << (TQ_UINT32)id; - s << handle; - s << offset; // we don't have a convienient 64 bit int so set upper int to zero - s << data; - -// kdDebug(KIO_SFTP_DB) << "sftpWrite(): SSH2_FXP_WRITE, id:" -// << id << ", handle:" << handle << ", offset:" << offset << ", some data" << endl; - -// kdDebug(KIO_SFTP_DB) << "sftpWrite(): send packet [" << p << "]" << endl; - - putPacket(p); - getPacket(p); - -// kdDebug(KIO_SFTP_DB) << "sftpWrite(): received packet [" << p << "]" << endl; - - TQDataStream r(p, IO_ReadOnly); - TQ_UINT8 type; - - r >> type >> id; - if( id != expectedId ) { - kdError(KIO_SFTP_DB) << "sftpWrite(): sftp packet id mismatch, got " - << id << ", expected " << expectedId << endl; - return -1; - } - - if( type != SSH2_FXP_STATUS ) { - kdError(KIO_SFTP_DB) << "sftpWrite(): unexpected message type of " << type << endl; - return -1; - } - - TQ_UINT32 code; - r >> code; - return code; -} - - diff --git a/tdeioslave/sftp/kio_sftp.h b/tdeioslave/sftp/kio_sftp.h deleted file mode 100644 index 1674221b8..000000000 --- a/tdeioslave/sftp/kio_sftp.h +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - sftpProtocol.h - description - ------------------- - begin : Sat Jun 30 20:08:47 CDT 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu -***************************************************************************/ - -/*************************************************************************** - * * - * 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; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#ifndef __kio_sftp_h__ -#define __kio_sftp_h__ - -#include -#include -#include - -#include -#include -#include -#include - -#include "process.h" -#include "sftpfileattr.h" -#include "ksshprocess.h" - -#define KIO_SFTP_DB 7120 - - -class sftpProtocol : public TDEIO::SlaveBase -{ - -public: - sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket); - virtual ~sftpProtocol(); - virtual void setHost(const TQString& h, int port, const TQString& user, const TQString& pass); - virtual void get(const KURL& url); - virtual void listDir(const KURL& url) ; - virtual void mimetype(const KURL& url); - virtual void stat(const KURL& url); - virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite); - virtual void put(const KURL& url, int permissions, bool overwrite, bool resume); - virtual void closeConnection(); - virtual void slave_status(); - virtual void del(const KURL &url, bool isfile); - virtual void chmod(const KURL& url, int permissions); - virtual void symlink(const TQString& target, const KURL& dest, bool overwrite); - virtual void rename(const KURL& src, const KURL& dest, bool overwrite); - virtual void mkdir(const KURL&url, int permissions); - virtual void openConnection(); - -private: // Private variables - /** True if ioslave is connected to sftp server. */ - bool mConnected; - - /** Host we are connected to. */ - TQString mHost; - - /** Port we are connected to. */ - int mPort; - - /** Ssh process to which we send the sftp packets. */ - KSshProcess ssh; - - /** Username to use when connecting */ - TQString mUsername; - - /** User's password */ - TQString mPassword; - - /** Message id of the last sftp packet we sent. */ - unsigned int mMsgId; - - /** Type of packet we are expecting to receive next. */ - unsigned char mExpected; - - /** Version of the sftp protocol we are using. */ - int sftpVersion; - - struct Status - { - int code; - TDEIO::filesize_t size; - TQString text; - }; - -private: // private methods - bool getPacket(TQByteArray& msg); - - /* Type is a sftp packet type found in .sftp.h'. - * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. - * - * Returns true if the type is supported by the sftp protocol - * version negotiated by the client and server (sftpVersion). - */ - bool isSupportedOperation(int type); - /** Used to have the server canonicalize any given path name to an absolute path. - This is useful for converting path names containing ".." components or relative - pathnames without a leading slash into absolute paths. - Returns the canonicalized url. */ - int sftpRealPath(const KURL& url, KURL& newUrl); - - /** Send an sftp packet to stdin of the ssh process. */ - bool putPacket(TQByteArray& p); - /** Process SSH_FXP_STATUS packets. */ - void processStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Process SSH_FXP_STATUS packes and return the result. */ - Status doProcessStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Opens a directory handle for url.path. Returns true if succeeds. */ - int sftpOpenDirectory(const KURL& url, TQByteArray& handle); - /** Closes a directory or file handle. */ - int sftpClose(const TQByteArray& handle); - /** Send a sftp command to rename a file or directoy. */ - int sftpRename(const KURL& src, const KURL& dest); - /** Set a files attributes. */ - int sftpSetStat(const KURL& url, const sftpFileAttr& attr); - /** Sends a sftp command to remove a file or directory. */ - int sftpRemove(const KURL& url, bool isfile); - /** Creates a symlink named dest to target. */ - int sftpSymLink(const TQString& target, const KURL& dest); - /** Get directory listings. */ - int sftpReadDir(const TQByteArray& handle, const KURL& url); - /** Retrieves the destination of a link. */ - int sftpReadLink(const KURL& url, TQString& target); - /** Stats a file. */ - int sftpStat(const KURL& url, sftpFileAttr& attr); - /** No descriptions */ - int sftpOpen(const KURL& url, const TQ_UINT32 pflags, const sftpFileAttr& attr, TQByteArray& handle); - /** No descriptions */ - int sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data); - /** No descriptions */ - int sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data); - - /** Performs faster upload when the source is a local file... */ - void sftpCopyPut(const KURL& src, const KURL& dest, int mode, bool overwrite); - /** Performs faster download when the destination is a local file... */ - void sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite); - - /** */ - Status sftpGet( const KURL& src, TDEIO::filesize_t offset = 0, int fd = -1); - void sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd = -1); -}; -#endif diff --git a/tdeioslave/sftp/sftp.protocol b/tdeioslave/sftp/sftp.protocol index 3b915bff8..522b23b01 100644 --- a/tdeioslave/sftp/sftp.protocol +++ b/tdeioslave/sftp/sftp.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_sftp +exec=tdeio_sftp protocol=sftp input=none listing=Name,Type,Size,Date,Access,Owner,Group,Link diff --git a/tdeioslave/sftp/tdeio_sftp.cpp b/tdeioslave/sftp/tdeio_sftp.cpp new file mode 100644 index 000000000..f31ad03c6 --- /dev/null +++ b/tdeioslave/sftp/tdeio_sftp.cpp @@ -0,0 +1,2282 @@ +/*************************************************************************** + sftp.cpp - description + ------------------- + begin : Fri Jun 29 23:45:40 CDT 2001 + copyright : (C) 2001 by Lucas Fisher + email : ljfisher@purdue.edu + ***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +/* +DEBUGGING +We are pretty much left with kdDebug messages for debugging. We can't use a gdb +as described in the ioslave DEBUG.howto because tdeinit has to run in a terminal. +Ssh will detect this terminal and ask for a password there, but will just get garbage. +So we can't connect. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sftp.h" +#include "tdeio_sftp.h" +#include "atomicio.h" +#include "sftpfileattr.h" +#include "ksshprocess.h" + + +using namespace TDEIO; +extern "C" +{ + int KDE_EXPORT kdemain( int argc, char **argv ) + { + TDEInstance instance( "tdeio_sftp" ); + + kdDebug(KIO_SFTP_DB) << "*** Starting tdeio_sftp " << endl; + + if (argc != 4) { + kdDebug(KIO_SFTP_DB) << "Usage: tdeio_sftp protocol domain-socket1 domain-socket2" << endl; + exit(-1); + } + + sftpProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + + kdDebug(KIO_SFTP_DB) << "*** tdeio_sftp Done" << endl; + return 0; + } +} + + +/* + * This helper handles some special issues (blocking and interrupted + * system call) when writing to a file handle. + * + * @return 0 on success or an error code on failure (ERR_COULD_NOT_WRITE, + * ERR_DISK_FULL, ERR_CONNECTION_BROKEN). + */ +static int writeToFile (int fd, const char *buf, size_t len) +{ + while (len > 0) + { + ssize_t written = ::write(fd, buf, len); + if (written >= 0) + { + buf += written; + len -= written; + continue; + } + + switch(errno) + { + case EINTR: + continue; + case EPIPE: + return ERR_CONNECTION_BROKEN; + case ENOSPC: + return ERR_DISK_FULL; + default: + return ERR_COULD_NOT_WRITE; + } + } + return 0; +} + +sftpProtocol::sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket) + : SlaveBase("tdeio_sftp", pool_socket, app_socket), + mConnected(false), mPort(-1), mMsgId(0) { + kdDebug(KIO_SFTP_DB) << "sftpProtocol(): pid = " << getpid() << endl; +} + + +sftpProtocol::~sftpProtocol() { + kdDebug(KIO_SFTP_DB) << "~sftpProtocol(): pid = " << getpid() << endl; + closeConnection(); +} + +/** + * Type is a sftp packet type found in .sftp.h'. + * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. + * + * Returns true if the type is supported by the sftp protocol + * version negotiated by the client and server (sftpVersion). + */ +bool sftpProtocol::isSupportedOperation(int type) { + switch (type) { + case SSH2_FXP_VERSION: + case SSH2_FXP_STATUS: + case SSH2_FXP_HANDLE: + case SSH2_FXP_DATA: + case SSH2_FXP_NAME: + case SSH2_FXP_ATTRS: + case SSH2_FXP_INIT: + case SSH2_FXP_OPEN: + case SSH2_FXP_CLOSE: + case SSH2_FXP_READ: + case SSH2_FXP_WRITE: + case SSH2_FXP_LSTAT: + case SSH2_FXP_FSTAT: + case SSH2_FXP_SETSTAT: + case SSH2_FXP_FSETSTAT: + case SSH2_FXP_OPENDIR: + case SSH2_FXP_READDIR: + case SSH2_FXP_REMOVE: + case SSH2_FXP_MKDIR: + case SSH2_FXP_RMDIR: + case SSH2_FXP_REALPATH: + case SSH2_FXP_STAT: + return true; + case SSH2_FXP_RENAME: + return sftpVersion >= 2 ? true : false; + case SSH2_FXP_EXTENDED: + case SSH2_FXP_EXTENDED_REPLY: + case SSH2_FXP_READLINK: + case SSH2_FXP_SYMLINK: + return sftpVersion >= 3 ? true : false; + default: + kdDebug(KIO_SFTP_DB) << "isSupportedOperation(type:" + << type << "): unrecognized operation type" << endl; + break; + } + + return false; +} + +void sftpProtocol::copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) +{ + kdDebug(KIO_SFTP_DB) << "copy(): " << src << " -> " << dest << endl; + + bool srcLocal = src.isLocalFile(); + bool destLocal = dest.isLocalFile(); + + if ( srcLocal && !destLocal ) // Copy file -> sftp + sftpCopyPut(src, dest, permissions, overwrite); + else if ( destLocal && !srcLocal ) // Copy sftp -> file + sftpCopyGet(dest, src, permissions, overwrite); + else + error(ERR_UNSUPPORTED_ACTION, TQString::null); +} + +void sftpProtocol::sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite) +{ + kdDebug(KIO_SFTP_DB) << "sftpCopyGet(): " << src << " -> " << dest << endl; + + // Attempt to establish a connection... + openConnection(); + if( !mConnected ) + return; + + KDE_struct_stat buff_orig; + TQCString dest_orig ( TQFile::encodeName(dest.path()) ); + bool origExists = (KDE_lstat( dest_orig.data(), &buff_orig ) != -1); + + if (origExists) + { + if (S_ISDIR(buff_orig.st_mode)) + { + error(ERR_IS_DIRECTORY, dest.prettyURL()); + return; + } + + if (!overwrite) + { + error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); + return; + } + } + + TDEIO::filesize_t offset = 0; + TQCString dest_part ( dest_orig + ".part" ); + + int fd = -1; + bool partExists = false; + bool markPartial = config()->readBoolEntry("MarkPartial", true); + + if (markPartial) + { + KDE_struct_stat buff_part; + partExists = (KDE_stat( dest_part.data(), &buff_part ) != -1); + + if (partExists && buff_part.st_size > 0 && S_ISREG(buff_part.st_mode)) + { + if (canResume( buff_part.st_size )) + { + offset = buff_part.st_size; + kdDebug(KIO_SFTP_DB) << "sftpCopyGet: Resuming @ " << offset << endl; + } + } + + if (offset > 0) + { + fd = KDE_open(dest_part.data(), O_RDWR); + offset = KDE_lseek(fd, 0, SEEK_END); + if (offset == 0) + { + error(ERR_CANNOT_RESUME, dest.prettyURL()); + return; + } + } + else + { + // Set up permissions properly, based on what is done in file io-slave + int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); + int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); + fd = KDE_open(dest_part.data(), openFlags, initialMode); + } + } + else + { + // Set up permissions properly, based on what is done in file io-slave + int openFlags = (O_CREAT | O_TRUNC | O_WRONLY); + int initialMode = (mode == -1) ? 0666 : (mode | S_IWUSR); + fd = KDE_open(dest_orig.data(), openFlags, initialMode); + } + + if(fd == -1) + { + kdDebug(KIO_SFTP_DB) << "sftpCopyGet: Unable to open (" << fd << ") for writting." << endl; + if (errno == EACCES) + error (ERR_WRITE_ACCESS_DENIED, dest.prettyURL()); + else + error (ERR_CANNOT_OPEN_FOR_WRITING, dest.prettyURL()); + return; + } + + Status info = sftpGet(src, offset, fd); + if ( info.code != 0 ) + { + // Should we keep the partially downloaded file ?? + TDEIO::filesize_t size = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); + if (info.size < size) + ::remove(dest_part.data()); + + error(info.code, info.text); + return; + } + + if (::close(fd) != 0) + { + error(ERR_COULD_NOT_WRITE, dest.prettyURL()); + return; + } + + // + if (markPartial) + { + if (::rename(dest_part.data(), dest_orig.data()) != 0) + { + error (ERR_CANNOT_RENAME_PARTIAL, dest_part); + return; + } + } + + data(TQByteArray()); + kdDebug(KIO_SFTP_DB) << "sftpCopyGet(): emit finished()" << endl; + finished(); +} + +sftpProtocol::Status sftpProtocol::sftpGet( const KURL& src, TDEIO::filesize_t offset, int fd ) +{ + int code; + sftpFileAttr attr(remoteEncoding()); + + Status res; + res.code = 0; + res.size = 0; + + kdDebug(KIO_SFTP_DB) << "sftpGet(): " << src << endl; + + // stat the file first to get its size + if( (code = sftpStat(src, attr)) != SSH2_FX_OK ) { + return doProcessStatus(code, src.prettyURL()); + } + + // We cannot get file if it is a directory + if( attr.fileType() == S_IFDIR ) { + res.text = src.prettyURL(); + res.code = ERR_IS_DIRECTORY; + return res; + } + + TDEIO::filesize_t fileSize = attr.fileSize(); + TQ_UINT32 pflags = SSH2_FXF_READ; + attr.clear(); + + TQByteArray handle; + if( (code = sftpOpen(src, pflags, attr, handle)) != SSH2_FX_OK ) { + res.text = src.prettyURL(); + res.code = ERR_CANNOT_OPEN_FOR_READING; + return res; + } + + // needed for determining mimetype + // note: have to emit mimetype before emitting totalsize. + TQByteArray buff; + TQByteArray mimeBuffer; + + unsigned int oldSize; + bool foundMimetype = false; + + // How big should each data packet be? Definitely not bigger than 64kb or + // you will overflow the 2 byte size variable in a sftp packet. + TQ_UINT32 len = 60*1024; + code = SSH2_FX_OK; + + kdDebug(KIO_SFTP_DB) << "sftpGet(): offset = " << offset << endl; + while( code == SSH2_FX_OK ) { + if( (code = sftpRead(handle, offset, len, buff)) == SSH2_FX_OK ) { + offset += buff.size(); + + // save data for mimetype. Pretty much follows what is in the ftp ioslave + if( !foundMimetype ) { + oldSize = mimeBuffer.size(); + mimeBuffer.resize(oldSize + buff.size()); + memcpy(mimeBuffer.data()+oldSize, buff.data(), buff.size()); + + if( mimeBuffer.size() > 1024 || offset == fileSize ) { + // determine mimetype + KMimeMagicResult* result = + KMimeMagic::self()->findBufferFileType(mimeBuffer, src.fileName()); + kdDebug(KIO_SFTP_DB) << "sftpGet(): mimetype is " << + result->mimeType() << endl; + mimeType(result->mimeType()); + + // Always send the total size after emitting mime-type... + totalSize(fileSize); + + if (fd == -1) + data(mimeBuffer); + else + { + if ( (res.code=writeToFile(fd, mimeBuffer.data(), mimeBuffer.size())) != 0 ) + return res; + } + + processedSize(mimeBuffer.size()); + mimeBuffer.resize(0); + foundMimetype = true; + } + } + else { + if (fd == -1) + data(buff); + else + { + if ( (res.code= writeToFile(fd, buff.data(), buff.size())) != 0 ) + return res; + } + processedSize(offset); + } + } + + /* + Check if slave was killed. According to slavebase.h we need to leave + the slave methods as soon as possible if the slave is killed. This + allows the slave to be cleaned up properly. + */ + if( wasKilled() ) { + res.text = i18n("An internal error occurred. Please retry the request again."); + res.code = ERR_UNKNOWN; + return res; + } + } + + if( code != SSH2_FX_EOF ) { + res.text = src.prettyURL(); + res.code = ERR_COULD_NOT_READ; // return here or still send empty array to indicate end of read? + } + + res.size = offset; + sftpClose(handle); + processedSize (offset); + return res; +} + +void sftpProtocol::get(const KURL& url) { + kdDebug(KIO_SFTP_DB) << "get(): " << url << endl ; + + openConnection(); + if( !mConnected ) + return; + + // Get resume offset + TQ_UINT64 offset = config()->readUnsignedLongNumEntry("resume"); + if( offset > 0 ) { + canResume(); + kdDebug(KIO_SFTP_DB) << "get(): canResume(), offset = " << offset << endl; + } + + Status info = sftpGet(url, offset); + + if (info.code != 0) + { + error(info.code, info.text); + return; + } + + data(TQByteArray()); + kdDebug(KIO_SFTP_DB) << "get(): emit finished()" << endl; + finished(); +} + + +void sftpProtocol::setHost (const TQString& h, int port, const TQString& user, const TQString& pass) +{ + kdDebug(KIO_SFTP_DB) << "setHost(): " << user << "@" << h << ":" << port << endl; + + if( mHost != h || mPort != port || user != mUsername || mPassword != pass ) + closeConnection(); + + mHost = h; + + if( port > 0 ) + mPort = port; + else { + mPort = -1; + } + + mUsername = user; + mPassword = pass; + + if (user.isEmpty()) + { + KUser u; + mUsername = u.loginName(); + } +} + + +void sftpProtocol::openConnection() { + + if(mConnected) + return; + + kdDebug(KIO_SFTP_DB) << "openConnection(): " << mUsername << "@" + << mHost << ":" << mPort << endl; + + infoMessage( i18n("Opening SFTP connection to host %1:%2").arg(mHost).arg(mPort)); + + if( mHost.isEmpty() ) { + kdDebug(KIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; + error(ERR_UNKNOWN_HOST, i18n("No hostname specified")); + return; + } + + //////////////////////////////////////////////////////////////////////////// + // Setup AuthInfo for use with password caching and the + // password dialog box. + AuthInfo info; + info.url.setProtocol("sftp"); + info.url.setHost(mHost); + info.url.setPort(mPort); + info.url.setUser(mUsername); + info.caption = i18n("SFTP Login"); + info.comment = "sftp://" + mHost + ":" + TQString::number(mPort); + info.commentLabel = i18n("site:"); + info.username = mUsername; + info.keepPassword = true; + + /////////////////////////////////////////////////////////////////////////// + // Check for cached authentication info if a username AND password were + // not specified in setHost(). + if( mUsername.isEmpty() && mPassword.isEmpty() ) { + kdDebug(KIO_SFTP_DB) << "openConnection(): checking cache " + << "info.username = " << info.username + << ", info.url = " << info.url.prettyURL() << endl; + + if( checkCachedAuthentication(info) ) { + mUsername = info.username; + mPassword = info.password; + } + } + + /////////////////////////////////////////////////////////////////////////// + // Now setup our ssh options. If we found a cached username + // and password we set the SSH_PASSWORD and SSH_USERNAME + // options right away. Otherwise we wait. The other options are + // necessary for running sftp over ssh. + KSshProcess::SshOpt opt; // a ssh option, this can be reused + KSshProcess::SshOptList opts; // list of SshOpts + KSshProcess::SshOptListIterator passwdIt; // points to the opt in opts that specifies the password + KSshProcess::SshOptListIterator usernameIt; + +// opt.opt = KSshProcess::SSH_VERBOSE; +// opts.append(opt); +// opts.append(opt); + + if( mPort != -1 ) { + opt.opt = KSshProcess::SSH_PORT; + opt.num = mPort; + opts.append(opt); + } + + opt.opt = KSshProcess::SSH_SUBSYSTEM; + opt.str = "sftp"; + opts.append(opt); + + opt.opt = KSshProcess::SSH_FORWARDX11; + opt.boolean = false; + opts.append(opt); + + opt.opt = KSshProcess::SSH_FORWARDAGENT; + opt.boolean = false; + opts.append(opt); + + opt.opt = KSshProcess::SSH_PROTOCOL; + opt.num = 2; + opts.append(opt); + + opt.opt = KSshProcess::SSH_HOST; + opt.str = mHost; + opts.append(opt); + + opt.opt = KSshProcess::SSH_ESCAPE_CHAR; + opt.num = -1; // don't use any escape character + opts.append(opt); + + // set the username and password if we have them + if( !mUsername.isEmpty() ) { + opt.opt = KSshProcess::SSH_USERNAME; + opt.str = mUsername; + usernameIt = opts.append(opt); + } + + if( !mPassword.isEmpty() ) { + opt.opt = KSshProcess::SSH_PASSWD; + opt.str = mPassword; + passwdIt = opts.append(opt); + } + + ssh.setOptions(opts); + ssh.printArgs(); + + /////////////////////////////////////////////////////////////////////////// + // Start the ssh connection process. + // + + int err; // error code from KSshProcess + TQString msg; // msg for dialog box + TQString caption; // dialog box caption + bool firstTime = true; + bool dlgResult; + + while( !(mConnected = ssh.connect()) ) { + err = ssh.error(); + kdDebug(KIO_SFTP_DB) << "openConnection(): " + "Got " << err << " from KSshProcess::connect()" << endl; + + switch(err) { + case KSshProcess::ERR_NEED_PASSWD: + case KSshProcess::ERR_NEED_PASSPHRASE: + // At this point we know that either we didn't set + // an username or password in the ssh options list, + // or what we did pass did not work. Therefore we + // must prompt the user. + if( err == KSshProcess::ERR_NEED_PASSPHRASE ) + info.prompt = i18n("Please enter your username and key passphrase."); + else + info.prompt = i18n("Please enter your username and password."); + + kdDebug(KIO_SFTP_DB) << "openConnection(): info.username = " << info.username + << ", info.url = " << info.url.prettyURL() << endl; + + if( firstTime ) + dlgResult = openPassDlg(info); + else + dlgResult = openPassDlg(info, i18n("Incorrect username or password")); + + if( dlgResult ) { + if( info.username.isEmpty() || info.password.isEmpty() ) { + error(ERR_COULD_NOT_AUTHENTICATE, + i18n("Please enter a username and password")); + continue; + } + } + else { + // user canceled or dialog failed to open + error(ERR_USER_CANCELED, TQString::null); + kdDebug(KIO_SFTP_DB) << "openConnection(): user canceled, dlgResult = " << dlgResult << endl; + closeConnection(); + return; + } + + firstTime = false; + + // Check if the username has changed. SSH only accepts + // the username at startup. If the username has changed + // we must disconnect ssh, change the SSH_USERNAME + // option, and reset the option list. We will also set + // the password option so the user is not prompted for + // it again. + if( mUsername != info.username ) { + kdDebug(KIO_SFTP_DB) << "openConnection(): Username changed from " + << mUsername << " to " << info.username << endl; + + ssh.disconnect(); + + // if we haven't yet added the username + // or password option to the ssh options list then + // the iterators will be equal to the empty iterator. + // Create the opts now and add them to the opt list. + if( usernameIt == KSshProcess::SshOptListIterator() ) { + kdDebug(KIO_SFTP_DB) << "openConnection(): " + "Adding username to options list" << endl; + opt.opt = KSshProcess::SSH_USERNAME; + usernameIt = opts.append(opt); + } + + if( passwdIt == KSshProcess::SshOptListIterator() ) { + kdDebug(KIO_SFTP_DB) << "openConnection(): " + "Adding password to options list" << endl; + opt.opt = KSshProcess::SSH_PASSWD; + passwdIt = opts.append(opt); + } + + (*usernameIt).str = info.username; + (*passwdIt).str = info.password; + ssh.setOptions(opts); + ssh.printArgs(); + } + else { // just set the password + ssh.setPassword(info.password); + } + + mUsername = info.username; + mPassword = info.password; + + break; + + case KSshProcess::ERR_NEW_HOST_KEY: + caption = i18n("Warning: Cannot verify host's identity."); + msg = ssh.errorMsg(); + if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { + closeConnection(); + error(ERR_USER_CANCELED, TQString::null); + return; + } + ssh.acceptHostKey(true); + break; + + case KSshProcess::ERR_DIFF_HOST_KEY: + caption = i18n("Warning: Host's identity changed."); + msg = ssh.errorMsg(); + if( KMessageBox::Yes != messageBox(WarningYesNo, msg, caption) ) { + closeConnection(); + error(ERR_USER_CANCELED, TQString::null); + return; + } + ssh.acceptHostKey(true); + break; + + case KSshProcess::ERR_AUTH_FAILED: + infoMessage(i18n("Authentication failed.")); + error(ERR_COULD_NOT_LOGIN, i18n("Authentication failed.")); + return; + + case KSshProcess::ERR_AUTH_FAILED_NEW_KEY: + msg = ssh.errorMsg(); + error(ERR_COULD_NOT_LOGIN, msg); + return; + + case KSshProcess::ERR_AUTH_FAILED_DIFF_KEY: + msg = ssh.errorMsg(); + error(ERR_COULD_NOT_LOGIN, msg); + return; + + case KSshProcess::ERR_CLOSED_BY_REMOTE_HOST: + infoMessage(i18n("Connection failed.")); + caption = i18n("Connection closed by remote host."); + msg = ssh.errorMsg(); + messageBox(Information, msg, caption); + closeConnection(); + error(ERR_COULD_NOT_LOGIN, msg); + return; + + case KSshProcess::ERR_INTERACT: + case KSshProcess::ERR_INTERNAL: + case KSshProcess::ERR_UNKNOWN: + case KSshProcess::ERR_INVALID_STATE: + case KSshProcess::ERR_CANNOT_LAUNCH: + case KSshProcess::ERR_HOST_KEY_REJECTED: + default: + infoMessage(i18n("Connection failed.")); + caption = i18n("Unexpected SFTP error: %1").arg(err); + msg = ssh.errorMsg(); + messageBox(Information, msg, caption); + closeConnection(); + error(ERR_UNKNOWN, msg); + return; + } + } + + // catch all in case we did something wrong above + if( !mConnected ) { + error(ERR_INTERNAL, TQString::null); + return; + } + + // Now send init packet. + kdDebug(KIO_SFTP_DB) << "openConnection(): Sending SSH2_FXP_INIT packet." << endl; + TQByteArray p; + TQDataStream packet(p, IO_WriteOnly); + packet << (TQ_UINT32)5; // packet length + packet << (TQ_UINT8) SSH2_FXP_INIT; // packet type + packet << (TQ_UINT32)SSH2_FILEXFER_VERSION; // client version + + putPacket(p); + getPacket(p); + + TQDataStream s(p, IO_ReadOnly); + TQ_UINT32 version; + TQ_UINT8 type; + s >> type; + kdDebug(KIO_SFTP_DB) << "openConnection(): Got type " << type << endl; + + if( type == SSH2_FXP_VERSION ) { + s >> version; + kdDebug(KIO_SFTP_DB) << "openConnection(): Got server version " << version << endl; + + // XXX Get extensions here + sftpVersion = version; + + /* Server should return lowest common version supported by + * client and server, but double check just in case. + */ + if( sftpVersion > SSH2_FILEXFER_VERSION ) { + error(ERR_UNSUPPORTED_PROTOCOL, + i18n("SFTP version %1").arg(version)); + closeConnection(); + return; + } + } + else { + error(ERR_UNKNOWN, i18n("Protocol error.")); + closeConnection(); + return; + } + + // Login succeeded! + infoMessage(i18n("Successfully connected to %1").arg(mHost)); + info.url.setProtocol("sftp"); + info.url.setHost(mHost); + info.url.setPort(mPort); + info.url.setUser(mUsername); + info.username = mUsername; + info.password = mPassword; + kdDebug(KIO_SFTP_DB) << "sftpProtocol(): caching info.username = " << info.username << + ", info.url = " << info.url.prettyURL() << endl; + cacheAuthentication(info); + mConnected = true; + connected(); + + mPassword.fill('x'); + info.password.fill('x'); + + return; +} + +void sftpProtocol::closeConnection() { + kdDebug(KIO_SFTP_DB) << "closeConnection()" << endl; + ssh.disconnect(); + mConnected = false; +} + +void sftpProtocol::sftpCopyPut(const KURL& src, const KURL& dest, int permissions, bool overwrite) { + + KDE_struct_stat buff; + TQCString file (TQFile::encodeName(src.path())); + + if (KDE_lstat(file.data(), &buff) == -1) { + error (ERR_DOES_NOT_EXIST, src.prettyURL()); + return; + } + + if (S_ISDIR (buff.st_mode)) { + error (ERR_IS_DIRECTORY, src.prettyURL()); + return; + } + + int fd = KDE_open (file.data(), O_RDONLY); + if (fd == -1) { + error (ERR_CANNOT_OPEN_FOR_READING, src.prettyURL()); + return; + } + + totalSize (buff.st_size); + + sftpPut (dest, permissions, false, overwrite, fd); + + // Close the file descriptor... + ::close( fd ); +} + +void sftpProtocol::sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd ) { + + openConnection(); + if( !mConnected ) + return; + + kdDebug(KIO_SFTP_DB) << "sftpPut(): " << dest + << ", resume=" << resume + << ", overwrite=" << overwrite << endl; + + KURL origUrl( dest ); + sftpFileAttr origAttr(remoteEncoding()); + bool origExists = false; + + // Stat original (without part ext) to see if it already exists + int code = sftpStat(origUrl, origAttr); + + if( code == SSH2_FX_OK ) { + kdDebug(KIO_SFTP_DB) << "sftpPut(): already exists" << endl; + + // Delete remote file if its size is zero + if( origAttr.fileSize() == 0 ) { + if( sftpRemove(origUrl, true) != SSH2_FX_OK ) { + error(ERR_CANNOT_DELETE_ORIGINAL, origUrl.prettyURL()); + return; + } + } + else { + origExists = true; + } + } + else if( code != SSH2_FX_NO_SUCH_FILE ) { + processStatus(code, origUrl.prettyURL()); + return; + } + + // Do not waste time/resources with more remote stat calls if the file exists + // and we weren't instructed to overwrite it... + if( origExists && !overwrite ) { + error(ERR_FILE_ALREADY_EXIST, origUrl.prettyURL()); + return; + } + + // Stat file with part ext to see if it already exists... + KURL partUrl( origUrl ); + partUrl.setFileName( partUrl.fileName() + ".part" ); + + TQ_UINT64 offset = 0; + bool partExists = false; + bool markPartial = config()->readBoolEntry("MarkPartial", true); + + if( markPartial ) { + + sftpFileAttr partAttr(remoteEncoding()); + code = sftpStat(partUrl, partAttr); + + if( code == SSH2_FX_OK ) { + kdDebug(KIO_SFTP_DB) << "sftpPut(): .part file already exists" << endl; + partExists = true; + offset = partAttr.fileSize(); + + // If for some reason, both the original and partial files exist, + // skip resumption just like we would if the size of the partial + // file is zero... + if( origExists || offset == 0 ) + { + if( sftpRemove(partUrl, true) != SSH2_FX_OK ) { + error(ERR_CANNOT_DELETE_PARTIAL, partUrl.prettyURL()); + return; + } + + if( sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { + error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); + return; + } + + offset = 0; + } + else if( !overwrite && !resume ) { + if (fd != -1) + resume = (KDE_lseek(fd, offset, SEEK_SET) != -1); + else + resume = canResume( offset ); + + kdDebug(KIO_SFTP_DB) << "sftpPut(): can resume = " << resume + << ", offset = " << offset; + + if( !resume ) { + error(ERR_FILE_ALREADY_EXIST, partUrl.prettyURL()); + return; + } + } + else { + offset = 0; + } + } + else if( code == SSH2_FX_NO_SUCH_FILE ) { + if( origExists && sftpRename(origUrl, partUrl) != SSH2_FX_OK ) { + error(ERR_CANNOT_RENAME_ORIGINAL, origUrl.prettyURL()); + return; + } + } + else { + processStatus(code, partUrl.prettyURL()); + return; + } + } + + // Determine the url we will actually write to... + KURL writeUrl (markPartial ? partUrl:origUrl); + + TQ_UINT32 pflags = 0; + if( overwrite && !resume ) + pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_TRUNC; + else if( !overwrite && !resume ) + pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_EXCL; + else if( overwrite && resume ) + pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT; + else if( !overwrite && resume ) + pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT | SSH2_FXF_APPEND; + + sftpFileAttr attr(remoteEncoding()); + TQByteArray handle; + + // Set the permissions of the file we write to if it didn't already exist + // and the permission info is supplied, i.e it is not -1 + if( !partExists && !origExists && permissions != -1) + attr.setPermissions(permissions); + + code = sftpOpen( writeUrl, pflags, attr, handle ); + if( code != SSH2_FX_OK ) { + + // Rename the file back to its original name if a + // put fails due to permissions problems... + if( markPartial && overwrite ) { + (void) sftpRename(partUrl, origUrl); + writeUrl = origUrl; + } + + if( code == SSH2_FX_FAILURE ) { // assume failure means file exists + error(ERR_FILE_ALREADY_EXIST, writeUrl.prettyURL()); + return; + } + else { + processStatus(code, writeUrl.prettyURL()); + return; + } + } + + long nbytes; + TQByteArray buff; + + do { + + if( fd != -1 ) { + buff.resize( 16*1024 ); + if ( (nbytes = ::read(fd, buff.data(), buff.size())) > -1 ) + buff.resize( nbytes ); + } + else { + dataReq(); + nbytes = readData( buff ); + } + + if( nbytes >= 0 ) { + if( (code = sftpWrite(handle, offset, buff)) != SSH2_FX_OK ) { + error(ERR_COULD_NOT_WRITE, dest.prettyURL()); + return; + } + + offset += nbytes; + processedSize(offset); + + /* Check if slave was killed. According to slavebase.h we + * need to leave the slave methods as soon as possible if + * the slave is killed. This allows the slave to be cleaned + * up properly. + */ + if( wasKilled() ) { + sftpClose(handle); + closeConnection(); + error(ERR_UNKNOWN, i18n("An internal error occurred. Please try again.")); + return; + } + } + + } while( nbytes > 0 ); + + if( nbytes < 0 ) { + sftpClose(handle); + + if( markPartial ) { + // Remove remote file if it smaller than our keep size + uint minKeepSize = config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); + + if( sftpStat(writeUrl, attr) == SSH2_FX_OK ) { + if( attr.fileSize() < minKeepSize ) { + sftpRemove(writeUrl, true); + } + } + } + + error( ERR_UNKNOWN, i18n("Unknown error was encountered while copying the file " + "to '%1'. Please try again.").arg(dest.host()) ); + return; + } + + if( (code = sftpClose(handle)) != SSH2_FX_OK ) { + error(ERR_COULD_NOT_WRITE, writeUrl.prettyURL()); + return; + } + + // If wrote to a partial file, then remove the part ext + if( markPartial ) { + if( sftpRename(partUrl, origUrl) != SSH2_FX_OK ) { + error(ERR_CANNOT_RENAME_PARTIAL, origUrl.prettyURL()); + return; + } + } + + finished(); +} + +void sftpProtocol::put ( const KURL& url, int permissions, bool overwrite, bool resume ){ + kdDebug(KIO_SFTP_DB) << "put(): " << url << ", overwrite = " << overwrite + << ", resume = " << resume << endl; + + sftpPut( url, permissions, resume, overwrite ); +} + +void sftpProtocol::stat ( const KURL& url ){ + kdDebug(KIO_SFTP_DB) << "stat(): " << url << endl; + + openConnection(); + if( !mConnected ) + return; + + // If the stat URL has no path, do not attempt to determine the real + // path and do a redirect. KRun will simply ignore such requests. + // Instead, simply return the mime-type as a directory... + if( !url.hasPath() ) { + UDSEntry entry; + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = TQString::null; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + atom.m_str = mUsername; + entry.append( atom ); + atom.m_uds = TDEIO::UDS_GROUP; + entry.append( atom ); + + // no size + statEntry( entry ); + finished(); + return; + } + + int code; + sftpFileAttr attr(remoteEncoding()); + if( (code = sftpStat(url, attr)) != SSH2_FX_OK ) { + processStatus(code, url.prettyURL()); + return; + } + else { + //kdDebug() << "We sent and received stat packet ok" << endl; + attr.setFilename(url.fileName()); + statEntry(attr.entry()); + } + + finished(); + + kdDebug(KIO_SFTP_DB) << "stat: END" << endl; + return; +} + + +void sftpProtocol::mimetype ( const KURL& url ){ + kdDebug(KIO_SFTP_DB) << "mimetype(): " << url << endl; + + openConnection(); + if( !mConnected ) + return; + + TQ_UINT32 pflags = SSH2_FXF_READ; + TQByteArray handle, mydata; + sftpFileAttr attr(remoteEncoding()); + int code; + if( (code = sftpOpen(url, pflags, attr, handle)) != SSH2_FX_OK ) { + error(ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); + return; + } + + TQ_UINT32 len = 1024; // Get first 1k for determining mimetype + TQ_UINT64 offset = 0; + code = SSH2_FX_OK; + while( offset < len && code == SSH2_FX_OK ) { + if( (code = sftpRead(handle, offset, len, mydata)) == SSH2_FX_OK ) { + data(mydata); + offset += mydata.size(); + processedSize(offset); + + kdDebug(KIO_SFTP_DB) << "mimetype(): offset = " << offset << endl; + } + } + + + data(TQByteArray()); + processedSize(offset); + sftpClose(handle); + finished(); + kdDebug(KIO_SFTP_DB) << "mimetype(): END" << endl; +} + + +void sftpProtocol::listDir(const KURL& url) { + kdDebug(KIO_SFTP_DB) << "listDir(): " << url << endl; + + openConnection(); + if( !mConnected ) + return; + + if( !url.hasPath() ) { + KURL newUrl ( url ); + if( sftpRealPath(url, newUrl) == SSH2_FX_OK ) { + kdDebug(KIO_SFTP_DB) << "listDir: Redirecting to " << newUrl << endl; + redirection(newUrl); + finished(); + return; + } + } + + int code; + TQByteArray handle; + + if( (code = sftpOpenDirectory(url, handle)) != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "listDir(): open directory failed" << endl; + processStatus(code, url.prettyURL()); + return; + } + + + code = SSH2_FX_OK; + while( code == SSH2_FX_OK ) { + code = sftpReadDir(handle, url); + if( code != SSH2_FX_OK && code != SSH2_FX_EOF ) + processStatus(code, url.prettyURL()); + kdDebug(KIO_SFTP_DB) << "listDir(): return code = " << code << endl; + } + + if( (code = sftpClose(handle)) != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "listdir(): closing of directory failed" << endl; + processStatus(code, url.prettyURL()); + return; + } + + finished(); + kdDebug(KIO_SFTP_DB) << "listDir(): END" << endl; +} + +/** Make a directory. + OpenSSH does not follow the internet draft for sftp in this case. + The format of the mkdir request expected by OpenSSH sftp server is: + uint32 id + string path + ATTR attr + */ +void sftpProtocol::mkdir(const KURL&url, int permissions){ + + kdDebug(KIO_SFTP_DB) << "mkdir() creating dir: " << url.path() << endl; + + openConnection(); + if( !mConnected ) + return; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + sftpFileAttr attr(remoteEncoding()); + + if (permissions != -1) + attr.setPermissions(permissions); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); + s << (TQ_UINT8)SSH2_FXP_MKDIR; + s << id; + s.writeBytes(path.data(), len); + s << attr; + + kdDebug(KIO_SFTP_DB) << "mkdir(): packet size is " << p.size() << endl; + + putPacket(p); + getPacket(p); + + TQ_UINT8 type; + TQDataStream r(p, IO_ReadOnly); + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "mkdir: sftp packet id mismatch" << endl; + error(ERR_COULD_NOT_MKDIR, path); + finished(); + return; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "mkdir(): unexpected packet type of " << type << endl; + error(ERR_COULD_NOT_MKDIR, path); + finished(); + return; + } + + int code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "mkdir(): failed with code " << code << endl; + + // Check if mkdir failed because the directory already exists so that + // we can return the appropriate message... + sftpFileAttr dirAttr(remoteEncoding()); + if ( sftpStat(url, dirAttr) == SSH2_FX_OK ) + { + error( ERR_DIR_ALREADY_EXIST, url.prettyURL() ); + return; + } + + error(ERR_COULD_NOT_MKDIR, path); + } + + finished(); +} + +void sftpProtocol::rename(const KURL& src, const KURL& dest, bool overwrite){ + kdDebug(KIO_SFTP_DB) << "rename(" << src << " -> " << dest << ")" << endl; + + if (!isSupportedOperation(SSH2_FXP_RENAME)) { + error(ERR_UNSUPPORTED_ACTION, + i18n("The remote host does not support renaming files.")); + return; + } + + openConnection(); + if( !mConnected ) + return; + + // Always stat the destination before attempting to rename + // a file or a directory... + sftpFileAttr attr(remoteEncoding()); + int code = sftpStat(dest, attr); + + // If the destination directory, exists tell it to the job + // so it the proper action can be presented to the user... + if( code == SSH2_FX_OK ) + { + if (!overwrite) + { + if ( S_ISDIR(attr.permissions()) ) + error( TDEIO::ERR_DIR_ALREADY_EXIST, dest.url() ); + else + error( TDEIO::ERR_FILE_ALREADY_EXIST, dest.url() ); + return; + } + + // If overwrite is specified, then simply remove the existing file/dir first... + if( (code = sftpRemove( dest, !S_ISDIR(attr.permissions()) )) != SSH2_FX_OK ) + { + processStatus(code); + return; + } + } + + // Do the renaming... + if( (code = sftpRename(src, dest)) != SSH2_FX_OK ) { + processStatus(code); + return; + } + + finished(); + kdDebug(KIO_SFTP_DB) << "rename(): END" << endl; +} + +void sftpProtocol::symlink(const TQString& target, const KURL& dest, bool overwrite){ + kdDebug(KIO_SFTP_DB) << "symlink()" << endl; + + if (!isSupportedOperation(SSH2_FXP_SYMLINK)) { + error(ERR_UNSUPPORTED_ACTION, + i18n("The remote host does not support creating symbolic links.")); + return; + } + + openConnection(); + if( !mConnected ) + return; + + int code; + bool failed = false; + if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) { + if( overwrite ) { // try to delete the destination + sftpFileAttr attr(remoteEncoding()); + if( (code = sftpStat(dest, attr)) != SSH2_FX_OK ) { + failed = true; + } + else { + if( (code = sftpRemove(dest, !S_ISDIR(attr.permissions())) ) != SSH2_FX_OK ) { + failed = true; + } + else { + // XXX what if rename fails again? We have lost the file. + // Maybe rename dest to a temporary name first? If rename is + // successful, then delete? + if( (code = sftpSymLink(target, dest)) != SSH2_FX_OK ) + failed = true; + } + } + } + else if( code == SSH2_FX_FAILURE ) { + error(ERR_FILE_ALREADY_EXIST, dest.prettyURL()); + return; + } + else + failed = true; + } + + // What error code do we return? Code for the original symlink command + // or for the last command or for both? The second one is implemented here. + if( failed ) + processStatus(code); + + finished(); +} + +void sftpProtocol::chmod(const KURL& url, int permissions){ + TQString perms; + perms.setNum(permissions, 8); + kdDebug(KIO_SFTP_DB) << "chmod(" << url << ", " << perms << ")" << endl; + + openConnection(); + if( !mConnected ) + return; + + sftpFileAttr attr(remoteEncoding()); + + if (permissions != -1) + attr.setPermissions(permissions); + + int code; + if( (code = sftpSetStat(url, attr)) != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "chmod(): sftpSetStat failed with error " << code << endl; + if( code == SSH2_FX_FAILURE ) + error(ERR_CANNOT_CHMOD, TQString::null); + else + processStatus(code, url.prettyURL()); + } + finished(); +} + + +void sftpProtocol::del(const KURL &url, bool isfile){ + kdDebug(KIO_SFTP_DB) << "del(" << url << ", " << (isfile?"file":"dir") << ")" << endl; + + openConnection(); + if( !mConnected ) + return; + + int code; + if( (code = sftpRemove(url, isfile)) != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "del(): sftpRemove failed with error code " << code << endl; + processStatus(code, url.prettyURL()); + } + finished(); +} + +void sftpProtocol::slave_status() { + kdDebug(KIO_SFTP_DB) << "slave_status(): connected to " + << mHost << "? " << mConnected << endl; + + slaveStatus ((mConnected ? mHost : TQString::null), mConnected); +} + +bool sftpProtocol::getPacket(TQByteArray& msg) { + TQByteArray buf(4096); + + // Get the message length... + ssize_t len = atomicio(ssh.stdioFd(), buf.data(), 4, true /*read*/); + + if( len == 0 || len == -1 ) { + kdDebug(KIO_SFTP_DB) << "getPacket(): read of packet length failed, ret = " + << len << ", error =" << strerror(errno) << endl; + closeConnection(); + error( ERR_CONNECTION_BROKEN, mHost); + msg.resize(0); + return false; + } + + uint msgLen; + TQDataStream s(buf, IO_ReadOnly); + s >> msgLen; + + //kdDebug(KIO_SFTP_DB) << "getPacket(): Message size = " << msgLen << endl; + + msg.resize(0); + + TQBuffer b( msg ); + b.open( IO_WriteOnly ); + + while( msgLen ) { + len = atomicio(ssh.stdioFd(), buf.data(), kMin((uint)buf.size(), msgLen), true /*read*/); + + if( len == 0 || len == -1) { + TQString errmsg; + if (len == 0) + errmsg = i18n("Connection closed"); + else + errmsg = i18n("Could not read SFTP packet"); + kdDebug(KIO_SFTP_DB) << "getPacket(): nothing to read, ret = " << + len << ", error =" << strerror(errno) << endl; + closeConnection(); + error(ERR_CONNECTION_BROKEN, errmsg); + b.close(); + return false; + } + + b.writeBlock(buf.data(), len); + + //kdDebug(KIO_SFTP_DB) << "getPacket(): Read Message size = " << len << endl; + //kdDebug(KIO_SFTP_DB) << "getPacket(): Copy Message size = " << msg.size() << endl; + + msgLen -= len; + } + + b.close(); + + return true; +} + +/** Send an sftp packet to stdin of the ssh process. */ +bool sftpProtocol::putPacket(TQByteArray& p){ +// kdDebug(KIO_SFTP_DB) << "putPacket(): size == " << p.size() << endl; + int ret; + ret = atomicio(ssh.stdioFd(), p.data(), p.size(), false /*write*/); + if( ret <= 0 ) { + kdDebug(KIO_SFTP_DB) << "putPacket(): write failed, ret =" << ret << + ", error = " << strerror(errno) << endl; + return false; + } + + return true; +} + +/** Used to have the server canonicalize any given path name to an absolute path. +This is useful for converting path names containing ".." components or relative +pathnames without a leading slash into absolute paths. +Returns the canonicalized url. */ +int sftpProtocol::sftpRealPath(const KURL& url, KURL& newUrl){ + + kdDebug(KIO_SFTP_DB) << "sftpRealPath(" << url << ", newUrl)" << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << TQ_UINT32(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); + s << (TQ_UINT8)SSH2_FXP_REALPATH; + s << id; + s.writeBytes(path.data(), len); + + putPacket(p); + getPacket(p); + + TQ_UINT8 type; + TQDataStream r(p, IO_ReadOnly); + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpRealPath: sftp packet id mismatch" << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 code; + r >> code; + return code; + } + + if( type != SSH2_FXP_NAME ) { + kdError(KIO_SFTP_DB) << "sftpRealPath(): unexpected packet type of " << type << endl; + return -1; + } + + TQ_UINT32 count; + r >> count; + if( count != 1 ) { + kdError(KIO_SFTP_DB) << "sftpRealPath(): Bad number of file attributes for realpath command" << endl; + return -1; + } + + TQCString newPath; + r >> newPath; + + newPath.truncate(newPath.size()); + if (newPath.isEmpty()) + newPath = "/"; + newUrl.setPath(newPath); + + return SSH2_FX_OK; +} + +sftpProtocol::Status sftpProtocol::doProcessStatus(TQ_UINT8 code, const TQString& message) +{ + Status res; + res.code = 0; + res.size = 0; + res.text = message; + + switch(code) + { + case SSH2_FX_OK: + case SSH2_FX_EOF: + break; + case SSH2_FX_NO_SUCH_FILE: + res.code = ERR_DOES_NOT_EXIST; + break; + case SSH2_FX_PERMISSION_DENIED: + res.code = ERR_ACCESS_DENIED; + break; + case SSH2_FX_FAILURE: + res.text = i18n("SFTP command failed for an unknown reason."); + res.code = ERR_UNKNOWN; + break; + case SSH2_FX_BAD_MESSAGE: + res.text = i18n("The SFTP server received a bad message."); + res.code = ERR_UNKNOWN; + break; + case SSH2_FX_OP_UNSUPPORTED: + res.text = i18n("You attempted an operation unsupported by the SFTP server."); + res.code = ERR_UNKNOWN; + break; + default: + res.text = i18n("Error code: %1").arg(code); + res.code = ERR_UNKNOWN; + } + + return res; +} + +/** Process SSH_FXP_STATUS packets. */ +void sftpProtocol::processStatus(TQ_UINT8 code, const TQString& message){ + Status st = doProcessStatus( code, message ); + if( st.code != 0 ) + error( st.code, st.text ); +} + +/** Opens a directory handle for url.path. Returns true if succeeds. */ +int sftpProtocol::sftpOpenDirectory(const KURL& url, TQByteArray& handle){ + + kdDebug(KIO_SFTP_DB) << "sftpOpenDirectory(" << url << ", handle)" << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); + s << (TQ_UINT8)SSH2_FXP_OPENDIR; + s << (TQ_UINT32)id; + s.writeBytes(path.data(), len); + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpOpenDirectory: sftp packet id mismatch: " << + "expected " << expectedId << ", got " << id << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 errCode; + r >> errCode; + return errCode; + } + + if( type != SSH2_FXP_HANDLE ) { + kdError(KIO_SFTP_DB) << "sftpOpenDirectory: unexpected message type of " << type << endl; + return -1; + } + + r >> handle; + if( handle.size() > 256 ) { + kdError(KIO_SFTP_DB) << "sftpOpenDirectory: handle exceeds max length" << endl; + return -1; + } + + kdDebug(KIO_SFTP_DB) << "sftpOpenDirectory: handle (" << handle.size() << "): [" << handle << "]" << endl; + return SSH2_FX_OK; +} + +/** Closes a directory or file handle. */ +int sftpProtocol::sftpClose(const TQByteArray& handle){ + + kdDebug(KIO_SFTP_DB) << "sftpClose()" << endl; + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); + s << (TQ_UINT8)SSH2_FXP_CLOSE; + s << (TQ_UINT32)id; + s << handle; + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpClose: sftp packet id mismatch" << endl; + return -1; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "sftpClose: unexpected message type of " << type << endl; + return -1; + } + + TQ_UINT32 code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "sftpClose: close failed with err code " << code << endl; + } + + return code; +} + +/** Set a files attributes. */ +int sftpProtocol::sftpSetStat(const KURL& url, const sftpFileAttr& attr){ + + kdDebug(KIO_SFTP_DB) << "sftpSetStat(" << url << ", attr)" << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len + attr.size()); + s << (TQ_UINT8)SSH2_FXP_SETSTAT; + s << (TQ_UINT32)id; + s.writeBytes(path.data(), len); + s << attr; + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpSetStat(): sftp packet id mismatch" << endl; + return -1; + // XXX How do we do a fatal error? + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "sftpSetStat(): unexpected message type of " << type << endl; + return -1; + } + + TQ_UINT32 code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "sftpSetStat(): set stat failed with err code " << code << endl; + } + + return code; +} + +/** Sends a sftp command to remove a file or directory. */ +int sftpProtocol::sftpRemove(const KURL& url, bool isfile){ + + kdDebug(KIO_SFTP_DB) << "sftpRemove(): " << url << ", isFile ? " << isfile << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); + s << (TQ_UINT8)(isfile ? SSH2_FXP_REMOVE : SSH2_FXP_RMDIR); + s << (TQ_UINT32)id; + s.writeBytes(path.data(), len); + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "del(): sftp packet id mismatch" << endl; + return -1; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "del(): unexpected message type of " << type << endl; + return -1; + } + + TQ_UINT32 code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "del(): del failed with err code " << code << endl; + } + + return code; +} + +/** Send a sftp command to rename a file or directoy. */ +int sftpProtocol::sftpRename(const KURL& src, const KURL& dest){ + + kdDebug(KIO_SFTP_DB) << "sftpRename(" << src << " -> " << dest << ")" << endl; + + TQCString srcPath = remoteEncoding()->encode(src.path()); + TQCString destPath = remoteEncoding()->encode(dest.path()); + + uint slen = srcPath.length(); + uint dlen = destPath.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + + 4 /*str length*/ + slen + + 4 /*str length*/ + dlen); + s << (TQ_UINT8)SSH2_FXP_RENAME; + s << (TQ_UINT32)id; + s.writeBytes(srcPath.data(), slen); + s.writeBytes(destPath.data(), dlen); + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpRename(): sftp packet id mismatch" << endl; + return -1; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "sftpRename(): unexpected message type of " << type << endl; + return -1; + } + + int code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "sftpRename(): rename failed with err code " << code << endl; + } + + return code; +} +/** Get directory listings. */ +int sftpProtocol::sftpReadDir(const TQByteArray& handle, const KURL& url){ + // url is needed so we can lookup the link destination + kdDebug(KIO_SFTP_DB) << "sftpReadDir(): " << url << endl; + + TQ_UINT32 id, expectedId, count; + TQ_UINT8 type; + + sftpFileAttr attr (remoteEncoding()); + attr.setDirAttrsFlag(true); + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + id = expectedId = mMsgId++; + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + handle.size()); + s << (TQ_UINT8)SSH2_FXP_READDIR; + s << (TQ_UINT32)id; + s << handle; + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + r >> type >> id; + + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpReadDir(): sftp packet id mismatch" << endl; + return -1; + } + + int code; + if( type == SSH2_FXP_STATUS ) { + r >> code; + return code; + } + + if( type != SSH2_FXP_NAME ) { + kdError(KIO_SFTP_DB) << "tdeio_sftpProtocl::sftpReadDir(): Unexpected message" << endl; + return -1; + } + + r >> count; + kdDebug(KIO_SFTP_DB) << "sftpReadDir(): got " << count << " entries" << endl; + + while(count--) { + r >> attr; + + if( S_ISLNK(attr.permissions()) ) { + KURL myurl ( url ); + myurl.addPath(attr.filename()); + + // Stat the symlink to find out its type... + sftpFileAttr attr2 (remoteEncoding()); + (void) sftpStat(myurl, attr2); + + attr.setLinkType(attr2.linkType()); + attr.setLinkDestination(attr2.linkDestination()); + } + + listEntry(attr.entry(), false); + } + + listEntry(attr.entry(), true); + + return SSH2_FX_OK; +} + +int sftpProtocol::sftpReadLink(const KURL& url, TQString& target){ + + kdDebug(KIO_SFTP_DB) << "sftpReadLink(): " << url << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + //kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Encoded Path: " << path << endl; + //kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Encoded Size: " << len << endl; + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); + s << (TQ_UINT8)SSH2_FXP_READLINK; + s << id; + s.writeBytes(path.data(), len); + + + putPacket(p); + getPacket(p); + + TQ_UINT8 type; + TQDataStream r(p, IO_ReadOnly); + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpReadLink(): sftp packet id mismatch" << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 code; + r >> code; + kdDebug(KIO_SFTP_DB) << "sftpReadLink(): read link failed with code " << code << endl; + return code; + } + + if( type != SSH2_FXP_NAME ) { + kdError(KIO_SFTP_DB) << "sftpReadLink(): unexpected packet type of " << type << endl; + return -1; + } + + TQ_UINT32 count; + r >> count; + if( count != 1 ) { + kdError(KIO_SFTP_DB) << "sftpReadLink(): Bad number of file attributes for realpath command" << endl; + return -1; + } + + TQCString linkAddress; + r >> linkAddress; + + linkAddress.truncate(linkAddress.size()); + kdDebug(KIO_SFTP_DB) << "sftpReadLink(): Link address: " << linkAddress << endl; + + target = remoteEncoding()->decode(linkAddress); + + return SSH2_FX_OK; +} + +int sftpProtocol::sftpSymLink(const TQString& _target, const KURL& dest){ + + TQCString destPath = remoteEncoding()->encode(dest.path()); + TQCString target = remoteEncoding()->encode(_target); + uint dlen = destPath.length(); + uint tlen = target.length(); + + kdDebug(KIO_SFTP_DB) << "sftpSymLink(" << target << " -> " << destPath << ")" << endl; + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + + 4 /*str length*/ + tlen + + 4 /*str length*/ + dlen); + s << (TQ_UINT8)SSH2_FXP_SYMLINK; + s << (TQ_UINT32)id; + s.writeBytes(target.data(), tlen); + s.writeBytes(destPath.data(), dlen); + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpSymLink(): sftp packet id mismatch" << endl; + return -1; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "sftpSymLink(): unexpected message type of " << type << endl; + return -1; + } + + TQ_UINT32 code; + r >> code; + if( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "sftpSymLink(): rename failed with err code " << code << endl; + } + + return code; +} + +/** Stats a file. */ +int sftpProtocol::sftpStat(const KURL& url, sftpFileAttr& attr) { + + kdDebug(KIO_SFTP_DB) << "sftpStat(): " << url << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + 4 /*str length*/ + len); + s << (TQ_UINT8)SSH2_FXP_LSTAT; + s << (TQ_UINT32)id; + s.writeBytes(path.data(), len); + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpStat(): sftp packet id mismatch" << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 errCode; + r >> errCode; + kdError(KIO_SFTP_DB) << "sftpStat(): stat failed with code " << errCode << endl; + return errCode; + } + + if( type != SSH2_FXP_ATTRS ) { + kdError(KIO_SFTP_DB) << "sftpStat(): unexpected message type of " << type << endl; + return -1; + } + + r >> attr; + attr.setFilename(url.fileName()); + kdDebug(KIO_SFTP_DB) << "sftpStat(): " << attr << endl; + + // If the stat'ed resource is a symlink, perform a recursive stat + // to determine the actual destination's type (file/dir). + if( S_ISLNK(attr.permissions()) && isSupportedOperation(SSH2_FXP_READLINK) ) { + + TQString target; + int code = sftpReadLink( url, target ); + + if ( code != SSH2_FX_OK ) { + kdError(KIO_SFTP_DB) << "sftpStat(): Unable to stat symlink destination" << endl; + return -1; + } + + kdDebug(KIO_SFTP_DB) << "sftpStat(): Resource is a symlink to -> " << target << endl; + + KURL dest( url ); + if( target[0] == '/' ) + dest.setPath(target); + else + dest.setFileName(target); + + dest.cleanPath(); + + // Ignore symlinks that point to themselves... + if ( dest != url ) { + + sftpFileAttr attr2 (remoteEncoding()); + (void) sftpStat(dest, attr2); + + if (attr2.linkType() == 0) + attr.setLinkType(attr2.fileType()); + else + attr.setLinkType(attr2.linkType()); + + attr.setLinkDestination(target); + + kdDebug(KIO_SFTP_DB) << "sftpStat(): File type: " << attr.fileType() << endl; + } + } + + return SSH2_FX_OK; +} + + +int sftpProtocol::sftpOpen(const KURL& url, const TQ_UINT32 pflags, + const sftpFileAttr& attr, TQByteArray& handle) { + kdDebug(KIO_SFTP_DB) << "sftpOpen(" << url << ", handle" << endl; + + TQCString path = remoteEncoding()->encode(url.path()); + uint len = path.length(); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + + 4 /*str length*/ + len + + 4 /*pflags*/ + attr.size()); + s << (TQ_UINT8)SSH2_FXP_OPEN; + s << (TQ_UINT32)id; + s.writeBytes(path.data(), len); + s << pflags; + s << attr; + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpOpen(): sftp packet id mismatch" << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 errCode; + r >> errCode; + return errCode; + } + + if( type != SSH2_FXP_HANDLE ) { + kdError(KIO_SFTP_DB) << "sftpOpen(): unexpected message type of " << type << endl; + return -1; + } + + r >> handle; + if( handle.size() > 256 ) { + kdError(KIO_SFTP_DB) << "sftpOpen(): handle exceeds max length" << endl; + return -1; + } + + kdDebug(KIO_SFTP_DB) << "sftpOpen(): handle (" << handle.size() << "): [" << handle << "]" << endl; + return SSH2_FX_OK; +} + + +int sftpProtocol::sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data) +{ + // kdDebug(KIO_SFTP_DB) << "sftpRead( offset = " << offset << ", len = " << len << ")" << endl; + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + + 4 /*str length*/ + handle.size() + + 8 /*offset*/ + 4 /*length*/); + s << (TQ_UINT8)SSH2_FXP_READ; + s << (TQ_UINT32)id; + s << handle; + s << offset; // we don't have a convienient 64 bit int so set upper int to zero + s << len; + + putPacket(p); + getPacket(p); + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpRead: sftp packet id mismatch" << endl; + return -1; + } + + if( type == SSH2_FXP_STATUS ) { + TQ_UINT32 errCode; + r >> errCode; + kdError(KIO_SFTP_DB) << "sftpRead: read failed with code " << errCode << endl; + return errCode; + } + + if( type != SSH2_FXP_DATA ) { + kdError(KIO_SFTP_DB) << "sftpRead: unexpected message type of " << type << endl; + return -1; + } + + r >> data; + + return SSH2_FX_OK; +} + + +int sftpProtocol::sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data){ +// kdDebug(KIO_SFTP_DB) << "sftpWrite( offset = " << offset << +// ", data sz = " << data.size() << ")" << endl; + TQByteArray p; + TQDataStream s(p, IO_WriteOnly); + + TQ_UINT32 id, expectedId; + id = expectedId = mMsgId++; + s << (TQ_UINT32)(1 /*type*/ + 4 /*id*/ + + 4 /*str length*/ + handle.size() + + 8 /*offset*/ + + 4 /* data size */ + data.size()); + s << (TQ_UINT8)SSH2_FXP_WRITE; + s << (TQ_UINT32)id; + s << handle; + s << offset; // we don't have a convienient 64 bit int so set upper int to zero + s << data; + +// kdDebug(KIO_SFTP_DB) << "sftpWrite(): SSH2_FXP_WRITE, id:" +// << id << ", handle:" << handle << ", offset:" << offset << ", some data" << endl; + +// kdDebug(KIO_SFTP_DB) << "sftpWrite(): send packet [" << p << "]" << endl; + + putPacket(p); + getPacket(p); + +// kdDebug(KIO_SFTP_DB) << "sftpWrite(): received packet [" << p << "]" << endl; + + TQDataStream r(p, IO_ReadOnly); + TQ_UINT8 type; + + r >> type >> id; + if( id != expectedId ) { + kdError(KIO_SFTP_DB) << "sftpWrite(): sftp packet id mismatch, got " + << id << ", expected " << expectedId << endl; + return -1; + } + + if( type != SSH2_FXP_STATUS ) { + kdError(KIO_SFTP_DB) << "sftpWrite(): unexpected message type of " << type << endl; + return -1; + } + + TQ_UINT32 code; + r >> code; + return code; +} + + diff --git a/tdeioslave/sftp/tdeio_sftp.h b/tdeioslave/sftp/tdeio_sftp.h new file mode 100644 index 000000000..23ff101b7 --- /dev/null +++ b/tdeioslave/sftp/tdeio_sftp.h @@ -0,0 +1,149 @@ +/*************************************************************************** + sftpProtocol.h - description + ------------------- + begin : Sat Jun 30 20:08:47 CDT 2001 + copyright : (C) 2001 by Lucas Fisher + email : ljfisher@purdue.edu +***************************************************************************/ + +/*************************************************************************** + * * + * 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; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef __tdeio_sftp_h__ +#define __tdeio_sftp_h__ + +#include +#include +#include + +#include +#include +#include +#include + +#include "process.h" +#include "sftpfileattr.h" +#include "ksshprocess.h" + +#define KIO_SFTP_DB 7120 + + +class sftpProtocol : public TDEIO::SlaveBase +{ + +public: + sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket); + virtual ~sftpProtocol(); + virtual void setHost(const TQString& h, int port, const TQString& user, const TQString& pass); + virtual void get(const KURL& url); + virtual void listDir(const KURL& url) ; + virtual void mimetype(const KURL& url); + virtual void stat(const KURL& url); + virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite); + virtual void put(const KURL& url, int permissions, bool overwrite, bool resume); + virtual void closeConnection(); + virtual void slave_status(); + virtual void del(const KURL &url, bool isfile); + virtual void chmod(const KURL& url, int permissions); + virtual void symlink(const TQString& target, const KURL& dest, bool overwrite); + virtual void rename(const KURL& src, const KURL& dest, bool overwrite); + virtual void mkdir(const KURL&url, int permissions); + virtual void openConnection(); + +private: // Private variables + /** True if ioslave is connected to sftp server. */ + bool mConnected; + + /** Host we are connected to. */ + TQString mHost; + + /** Port we are connected to. */ + int mPort; + + /** Ssh process to which we send the sftp packets. */ + KSshProcess ssh; + + /** Username to use when connecting */ + TQString mUsername; + + /** User's password */ + TQString mPassword; + + /** Message id of the last sftp packet we sent. */ + unsigned int mMsgId; + + /** Type of packet we are expecting to receive next. */ + unsigned char mExpected; + + /** Version of the sftp protocol we are using. */ + int sftpVersion; + + struct Status + { + int code; + TDEIO::filesize_t size; + TQString text; + }; + +private: // private methods + bool getPacket(TQByteArray& msg); + + /* Type is a sftp packet type found in .sftp.h'. + * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. + * + * Returns true if the type is supported by the sftp protocol + * version negotiated by the client and server (sftpVersion). + */ + bool isSupportedOperation(int type); + /** Used to have the server canonicalize any given path name to an absolute path. + This is useful for converting path names containing ".." components or relative + pathnames without a leading slash into absolute paths. + Returns the canonicalized url. */ + int sftpRealPath(const KURL& url, KURL& newUrl); + + /** Send an sftp packet to stdin of the ssh process. */ + bool putPacket(TQByteArray& p); + /** Process SSH_FXP_STATUS packets. */ + void processStatus(TQ_UINT8, const TQString& message = TQString::null); + /** Process SSH_FXP_STATUS packes and return the result. */ + Status doProcessStatus(TQ_UINT8, const TQString& message = TQString::null); + /** Opens a directory handle for url.path. Returns true if succeeds. */ + int sftpOpenDirectory(const KURL& url, TQByteArray& handle); + /** Closes a directory or file handle. */ + int sftpClose(const TQByteArray& handle); + /** Send a sftp command to rename a file or directoy. */ + int sftpRename(const KURL& src, const KURL& dest); + /** Set a files attributes. */ + int sftpSetStat(const KURL& url, const sftpFileAttr& attr); + /** Sends a sftp command to remove a file or directory. */ + int sftpRemove(const KURL& url, bool isfile); + /** Creates a symlink named dest to target. */ + int sftpSymLink(const TQString& target, const KURL& dest); + /** Get directory listings. */ + int sftpReadDir(const TQByteArray& handle, const KURL& url); + /** Retrieves the destination of a link. */ + int sftpReadLink(const KURL& url, TQString& target); + /** Stats a file. */ + int sftpStat(const KURL& url, sftpFileAttr& attr); + /** No descriptions */ + int sftpOpen(const KURL& url, const TQ_UINT32 pflags, const sftpFileAttr& attr, TQByteArray& handle); + /** No descriptions */ + int sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data); + /** No descriptions */ + int sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data); + + /** Performs faster upload when the source is a local file... */ + void sftpCopyPut(const KURL& src, const KURL& dest, int mode, bool overwrite); + /** Performs faster download when the destination is a local file... */ + void sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite); + + /** */ + Status sftpGet( const KURL& src, TDEIO::filesize_t offset = 0, int fd = -1); + void sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd = -1); +}; +#endif diff --git a/tdeioslave/smb/CMakeLists.txt b/tdeioslave/smb/CMakeLists.txt index 2493c2a85..23cc1f000 100644 --- a/tdeioslave/smb/CMakeLists.txt +++ b/tdeioslave/smb/CMakeLists.txt @@ -32,12 +32,12 @@ install( FILES smb-network.desktop DESTINATION ${DATA_INSTALL_DIR}/remoteview ) install( FILES x-smb-workgroup.desktop x-smb-server.desktop DESTINATION ${MIME_INSTALL_DIR}/application ) -##### kio_smb (module) ########################## +##### tdeio_smb (module) ########################## -tde_add_kpart( kio_smb AUTOMOC +tde_add_kpart( tdeio_smb AUTOMOC SOURCES - kio_smb.cpp kio_smb_auth.cpp kio_smb_browse.cpp kio_smb_config.cpp - kio_smb_dir.cpp kio_smb_file.cpp kio_smb_internal.cpp kio_smb_mount.cpp + tdeio_smb.cpp tdeio_smb_auth.cpp tdeio_smb_browse.cpp tdeio_smb_config.cpp + tdeio_smb_dir.cpp tdeio_smb_file.cpp tdeio_smb_internal.cpp tdeio_smb_mount.cpp LINK tdeio-shared ${SMBCLIENT_LIBRARIES} DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/smb/Makefile.am b/tdeioslave/smb/Makefile.am index 97a4034da..ed3ef6d46 100644 --- a/tdeioslave/smb/Makefile.am +++ b/tdeioslave/smb/Makefile.am @@ -2,21 +2,21 @@ INCLUDES=$(all_includes) -kde_module_LTLIBRARIES = kio_smb.la -kio_smb_la_SOURCES = kio_smb.cpp \ - kio_smb_auth.cpp \ - kio_smb_browse.cpp \ - kio_smb_config.cpp \ - kio_smb_dir.cpp \ - kio_smb_file.cpp \ - kio_smb_internal.cpp \ - kio_smb_mount.cpp +kde_module_LTLIBRARIES = tdeio_smb.la +tdeio_smb_la_SOURCES = tdeio_smb.cpp \ + tdeio_smb_auth.cpp \ + tdeio_smb_browse.cpp \ + tdeio_smb_config.cpp \ + tdeio_smb_dir.cpp \ + tdeio_smb_file.cpp \ + tdeio_smb_internal.cpp \ + tdeio_smb_mount.cpp -kio_smb_la_LIBADD = -lkio -lsmbclient $(SMBCLIENT_EXTRA_LIBS) +tdeio_smb_la_LIBADD = -ltdeio -lsmbclient $(SMBCLIENT_EXTRA_LIBS) -kio_smb_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_smb_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -noinst_HEADERS = kio_smb.h kio_smb_internal.h +noinst_HEADERS = tdeio_smb.h tdeio_smb_internal.h kdelnk_DATA = smb.protocol diff --git a/tdeioslave/smb/kio_smb.cpp b/tdeioslave/smb/kio_smb.cpp deleted file mode 100644 index 193df965f..000000000 --- a/tdeioslave/smb/kio_smb.cpp +++ /dev/null @@ -1,77 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: Top level implementation file for kio_smb.cpp -// -// Abstract: member function implementations for SMBSlave -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include "kio_smb.h" -#include "kio_smb_internal.h" - -//=========================================================================== -SMBSlave::SMBSlave(const TQCString& pool, const TQCString& app) - : SlaveBase( "smb", pool, app ) -{ - m_initialized_smbc = false; - - //read in the default workgroup info... - reparseConfiguration(); - - //initialize the library... - auth_initialize_smbc(); -} - - -//=========================================================================== -SMBSlave::~SMBSlave() -{ -} - - -//=========================================================================== -// pointer to the slave created in kdemain -SMBSlave* G_TheSlave; - -//=========================================================================== -int KDE_EXPORT kdemain( int argc, char **argv ) -{ - - TDEInstance instance( "kio_smb" ); - if( argc != 4 ) - { - kdDebug(KIO_SMB) << "Usage: kio_smb protocol domain-socket1 domain-socket2" - << endl; - return -1; - } - - SMBSlave slave( argv[2], argv[3] ); - - G_TheSlave = &slave; - slave.dispatchLoop(); - - return 0; -} - diff --git a/tdeioslave/smb/kio_smb.h b/tdeioslave/smb/kio_smb.h deleted file mode 100644 index 34ad0200a..000000000 --- a/tdeioslave/smb/kio_smb.h +++ /dev/null @@ -1,301 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb.h -// -// Abstract: The main kio slave class declaration. For convenience, -// in concurrent devlopment, the implementation for this class -// is separated into several .cpp files -- the file containing -// the implementation should be noted in the comments for each -// member function. -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - - -#ifndef KIO_SMB_H_INCLUDED -#define KIO_SMB_H_INCLUDED - -//------------- -// QT includes -//------------- -#include -#include -#include -#include -#include - -//-------------- -// KDE includes -//-------------- -#include -#include -#include -#include -#include -#include - -//----------------------------- -// Standard C library includes -//----------------------------- -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//------------------------------- -// Samba client library includes -//------------------------------- -extern "C" -{ -#include -} - -//--------------------------- -// kio_smb internal includes -//--------------------------- -#include "kio_smb_internal.h" - -#define MAX_XFER_BUF_SIZE 16348 -#define KIO_SMB 7106 - -using namespace TDEIO; -class TDEProcess; - -//=========================================================================== - - -class SMBSlave : public TQObject, public TDEIO::SlaveBase -{ - Q_OBJECT - -private: - //--------------------------------------------------------------------- - // please make sure your private data does not duplicate existing data - //--------------------------------------------------------------------- - bool m_initialized_smbc; - - /** - * From Controlcenter - */ - TQString m_default_user; -// TQString m_default_workgroup; //currently unused, Alex - TQString m_default_password; - TQString m_default_encoding; - - /** - * we store the current url, it's needed for - * callback authorisation method - */ - SMBUrl m_current_url; - - /** - * From Controlcenter, show SHARE$ or not - */ -// bool m_showHiddenShares; //currently unused, Alex - - /** - * libsmbclient need global variables to store in, - * else it crashes on exit next method after use cache_stat, - * looks like gcc (C/C++) failure - */ - struct stat st; -protected: - //--------------------------------------------- - // Authentication functions (kio_smb_auth.cpp) - //--------------------------------------------- - // (please prefix functions with auth) - - - /** - * Description : Initilizes the libsmbclient - * Return : true on success false with errno set on error - */ - bool auth_initialize_smbc(); - - bool checkPassword(SMBUrl &url); - - - //--------------------------------------------- - // Cache functions (kio_smb_auth.cpp) - //--------------------------------------------- - - //Stat methods - - //----------------------------------------- - // Browsing functions (kio_smb_browse.cpp) - //----------------------------------------- - // (please prefix functions with browse) - - /** - * Description : Return a stat of given SMBUrl. Calls cache_stat and - * pack it in UDSEntry. UDSEntry will not be cleared - * Parameter : SMBUrl the url to stat - * ignore_errors do not call error(), but warning() - * Return : false if any error occoured (errno), else true - */ - bool browse_stat_path(const SMBUrl& url, UDSEntry& udsentry, bool ignore_errors); - - /** - * Description : call smbc_stat and return stats of the url - * Parameter : SMBUrl the url to stat - * Return : stat* of the url - * Note : it has some problems with stat in method, looks like - * something leave(or removed) on the stack. If your - * method segfault on returning try to change the stat* - * variable - */ - int cache_stat( const SMBUrl& url, struct stat* st ); - - //--------------------------------------------- - // Configuration functions (kio_smb_config.cpp) - //--------------------------------------------- - // (please prefix functions with config) - - - //--------------------------------------- - // Directory functions (kio_smb_dir.cpp) - //--------------------------------------- - // (please prefix functions with dir) - - - //-------------------------------------- - // File IO functions (kio_smb_file.cpp) - //-------------------------------------- - // (please prefix functions with file) - - //---------------------------- - // Misc functions (this file) - //---------------------------- - - - /** - * Description : correct a given URL - * valid URL's are - * - * smb://[[domain;]user[:password]@]server[:port][/share[/path[/file]]] - * smb:/[[domain;]user[:password]@][group/[server[/share[/path[/file]]]]] - * domain = workgroup(domain) of the user - * user = username - * password = password of useraccount - * group = workgroup(domain) of server - * server = host to connect - * share = a share of the server (host) - * path = a path of the share - * Parameter : KURL the url to check - * Return : new KURL if its corrected. else the same KURL - */ - KURL checkURL(const KURL& kurl) const; - - void reportError(const SMBUrl &kurl); - -public: - - //----------------------------------------------------------------------- - // smbclient authentication callback (note that this is called by the - // global ::auth_smbc_get_data() call. - void auth_smbc_get_data(const char *server,const char *share, - char *workgroup, int wgmaxlen, - char *username, int unmaxlen, - char *password, int pwmaxlen); - - - //----------------------------------------------------------------------- - // Overwritten functions from the base class that define the operation of - // this slave. (See the base class headerfile slavebase.h for more - // details) - //----------------------------------------------------------------------- - - // Functions overwritten in kio_smb.cpp - SMBSlave(const TQCString& pool, const TQCString& app); - virtual ~SMBSlave(); - - // Functions overwritten in kio_smb_browse.cpp - virtual void listDir( const KURL& url ); - virtual void stat( const KURL& url ); - - // Functions overwritten in kio_smb_config.cpp - virtual void reparseConfiguration(); - - // Functions overwritten in kio_smb_dir.cpp - virtual void copy( const KURL& src, const KURL &dest, int permissions, bool overwrite ); - virtual void del( const KURL& kurl, bool isfile); - virtual void mkdir( const KURL& kurl, int permissions ); - virtual void rename( const KURL& src, const KURL& dest, bool overwrite ); - - // Functions overwritten in kio_smb_file.cpp - virtual void get( const KURL& kurl ); - virtual void put( const KURL& kurl, int permissions, bool overwrite, bool resume ); - - // Functions not implemented (yet) - //virtual void setHost(const TQString& host, int port, const TQString& user, const TQString& pass); - //virtual void openConnection(); - //virtual void closeConnection(); - //virtual void slave_status(); - virtual void special( const TQByteArray & ); - -private slots: - void readOutput(TDEProcess *proc, char *buffer, int buflen); - void readStdErr(TDEProcess *proc, char *buffer, int buflen); - -private: - TQString mybuf, mystderr; - -}; - -//=========================================================================== -// pointer to the slave created in kdemain -extern SMBSlave* G_TheSlave; - - -//========================================================================== -// the global libsmbclient authentication callback function -extern "C" -{ - -void auth_smbc_get_data(const char *server,const char *share, - char *workgroup, int wgmaxlen, - char *username, int unmaxlen, - char *password, int pwmaxlen); - -} - - -//=========================================================================== -// Main slave entrypoint (see kio_smb.cpp) -extern "C" -{ - -int kdemain( int argc, char **argv ); - -} - - -#endif //#endif KIO_SMB_H_INCLUDED diff --git a/tdeioslave/smb/kio_smb_auth.cpp b/tdeioslave/smb/kio_smb_auth.cpp deleted file mode 100644 index f11d80b3a..000000000 --- a/tdeioslave/smb/kio_smb_auth.cpp +++ /dev/null @@ -1,207 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_auth.cpp -// -// Abstract: member function implementations for SMBSlave that deal with -// SMB directory access -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include "kio_smb.h" -#include "kio_smb_internal.h" - -#include -#include -#include - -// call for libsmbclient -//========================================================================== -void auth_smbc_get_data(const char *server,const char *share, - char *workgroup, int wgmaxlen, - char *username, int unmaxlen, - char *password, int pwmaxlen) -//========================================================================== -{ - G_TheSlave->auth_smbc_get_data(server, share, - workgroup,wgmaxlen, - username, unmaxlen, - password, pwmaxlen); -} - -//-------------------------------------------------------------------------- -void SMBSlave::auth_smbc_get_data(const char *server,const char *share, - char *workgroup, int wgmaxlen, - char *username, int unmaxlen, - char *password, int pwmaxlen) -//-------------------------------------------------------------------------- -{ - //check this to see if we "really" need to authenticate... - SMBUrlType t = m_current_url.getType(); - if( t == SMBURLTYPE_ENTIRE_NETWORK ) - { - kdDebug(KIO_SMB) << "we don't really need to authenticate for this top level url, returning" << endl; - return; - } - kdDebug(KIO_SMB) << "AAAAAAAAAAAAAA auth_smbc_get_dat: set user=" << username << ", workgroup=" << workgroup - << " server=" << server << ", share=" << share << endl; - - TQString s_server = TQString::fromUtf8(server); - TQString s_share = TQString::fromUtf8(share); - workgroup[wgmaxlen - 1] = 0; - TQString s_workgroup = TQString::fromUtf8(workgroup); - username[unmaxlen - 1] = 0; - TQString s_username = TQString::fromUtf8(username); - password[pwmaxlen - 1] = 0; - TQString s_password = TQString::fromUtf8(password); - - TDEIO::AuthInfo info; - info.url = KURL("smb:///"); - info.url.setHost(s_server); - info.url.setPath("/" + s_share); - - info.username = s_username; - info.password = s_password; - info.verifyPath = true; - - kdDebug(KIO_SMB) << "libsmb-auth-callback URL:" << info.url << endl; - - if ( !checkCachedAuthentication( info ) ) - { - if ( m_default_user.isEmpty() ) - { - // ok, we do not know the password. Let's try anonymous before we try for real - info.username = "anonymous"; - info.password = TQString::null; - } - else - { - // user defined a default username/password in kcontrol; try this - info.username = m_default_user; - info.password = m_default_password; - } - - } else - kdDebug(KIO_SMB) << "got password through cache" << endl; - - strncpy(username, info.username.utf8(), unmaxlen - 1); - strncpy(password, info.password.utf8(), pwmaxlen - 1); -} - -bool SMBSlave::checkPassword(SMBUrl &url) -{ - kdDebug(KIO_SMB) << "checkPassword for " << url << endl; - - TDEIO::AuthInfo info; - info.url = KURL("smb:///"); - info.url.setHost(url.host()); - - TQString share = url.path(); - int index = share.find('/', 1); - if (index > 1) - share = share.left(index); - if (share.at(0) == '/') - share = share.mid(1); - info.url.setPath("/" + share); - info.verifyPath = true; - - if ( share.isEmpty() ) - info.prompt = i18n( - "Please enter authentication information for %1" ) - .arg( url.host() ); - else - info.prompt = i18n( - "Please enter authentication information for:\n" - "Server = %1\n" - "Share = %2" ) - .arg( url.host() ) - .arg( share ); - - info.username = url.user(); - kdDebug(KIO_SMB) << "call openPassDlg for " << info.url << endl; - - if ( openPassDlg(info) ) { - kdDebug(KIO_SMB) << "openPassDlg returned " << info.username << endl; - url.setUser(info.username); - url.setPass(info.password); - return true; - } - kdDebug(KIO_SMB) << "no value from openPassDlg\n"; - return false; -} - -//-------------------------------------------------------------------------- -// Initalizes the smbclient library -// -// Returns: 0 on success -1 with errno set on error -bool SMBSlave::auth_initialize_smbc() -{ - SMBCCTX *smb_context = NULL; - - kdDebug(KIO_SMB) << "auth_initialize_smbc " << endl; - if(m_initialized_smbc == false) - { - kdDebug(KIO_SMB) << "smbc_init call" << endl; - KSimpleConfig cfg( "tdeioslaverc", true ); - - cfg.setGroup( "SMB" ); - int debug_level = cfg.readNumEntry( "DebugLevel", 0 ); - -#if 0 - /* old API initialisation routine does not allow to set flags */ - - if(smbc_init(::auth_smbc_get_data,debug_level) == -1) - { - SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to initialize")); - return false; - } -#endif - smb_context = smbc_new_context(); - if (smb_context == NULL) { - SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to create context")); - return false; - } - - smb_context->debug = debug_level; - smb_context->callbacks.auth_fn = ::auth_smbc_get_data; - - if (!smbc_init_context(smb_context)) { - smbc_free_context(smb_context, false); - smb_context = NULL; - SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to initialize context")); - return false; - } - -#if defined(SMB_CTX_FLAG_USE_KERBEROS) && defined(SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) - smb_context->flags |= SMB_CTX_FLAG_USE_KERBEROS | SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; -#endif - - smbc_set_context(smb_context); - - m_initialized_smbc = true; - } - - return true; -} - diff --git a/tdeioslave/smb/kio_smb_browse.cpp b/tdeioslave/smb/kio_smb_browse.cpp deleted file mode 100644 index 26c379bde..000000000 --- a/tdeioslave/smb/kio_smb_browse.cpp +++ /dev/null @@ -1,476 +0,0 @@ - -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_browse.cpp -// -// Abstract: member function implementations for SMBSlave that deal with -// SMB browsing -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include -#include -#include - -#include - -#include - -#include "kio_smb.h" -#include "kio_smb_internal.h" - -using namespace TDEIO; - -int SMBSlave::cache_stat(const SMBUrl &url, struct stat* st ) -{ - int result = smbc_stat( url.toSmbcUrl(), st); - kdDebug(KIO_SMB) << "smbc_stat " << url << " " << errno << " " << result << endl; - kdDebug(KIO_SMB) << "size " << (TDEIO::filesize_t)st->st_size << endl; - return result; -} - -//--------------------------------------------------------------------------- -bool SMBSlave::browse_stat_path(const SMBUrl& _url, UDSEntry& udsentry, bool ignore_errors) - // Returns: true on success, false on failure -{ - UDSAtom udsatom; - - SMBUrl url = _url; - - if(cache_stat(url, &st) == 0) - { - if(!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) - { - kdDebug(KIO_SMB)<<"SMBSlave::browse_stat_path mode: "<pw_name; - else - udsatom.m_str = TQString::number( uid ); - udsentry.append(udsatom); - - udsatom.m_uds = TDEIO::UDS_GROUP; - gid_t gid = st.st_gid; - struct group *grp = getgrgid( gid ); - if ( grp ) - udsatom.m_str = grp->gr_name; - else - udsatom.m_str = TQString::number( gid ); - udsentry.append(udsatom); - - udsatom.m_uds = TDEIO::UDS_ACCESS; - udsatom.m_long = st.st_mode & 07777; - udsentry.append(udsatom); - - udsatom.m_uds = UDS_MODIFICATION_TIME; - udsatom.m_long = st.st_mtime; - udsentry.append(udsatom); - - udsatom.m_uds = UDS_ACCESS_TIME; - udsatom.m_long = st.st_atime; - udsentry.append(udsatom); - - udsatom.m_uds = UDS_CREATION_TIME; - udsatom.m_long = st.st_ctime; - udsentry.append(udsatom); - - } - else - { - if (!ignore_errors) { - if (errno == EPERM || errno == EACCES) - if (checkPassword(url)) { - redirection( url ); - return false; - } - - reportError(url); - } else if (errno == ENOENT || errno == ENOTDIR) { - warning(i18n("File does not exist: %1").arg(url.url())); - } - kdDebug(KIO_SMB) << "SMBSlave::browse_stat_path ERROR!!"<< endl; - return false; - } - - return true; -} - -//=========================================================================== -void SMBSlave::stat( const KURL& kurl ) -{ - kdDebug(KIO_SMB) << "SMBSlave::stat on "<< kurl << endl; - // make a valid URL - KURL url = checkURL(kurl); - - // if URL is not valid we have to redirect to correct URL - if (url != kurl) - { - kdDebug() << "redirection " << url << endl; - redirection(url); - finished(); - return; - } - - m_current_url = url; - - UDSAtom udsatom; - UDSEntry udsentry; - // Set name - udsatom.m_uds = TDEIO::UDS_NAME; - udsatom.m_str = kurl.fileName(); - udsentry.append( udsatom ); - - switch(m_current_url.getType()) - { - case SMBURLTYPE_UNKNOWN: - error(ERR_MALFORMED_URL,m_current_url.prettyURL()); - finished(); - return; - - case SMBURLTYPE_ENTIRE_NETWORK: - case SMBURLTYPE_WORKGROUP_OR_SERVER: - udsatom.m_uds = TDEIO::UDS_FILE_TYPE; - udsatom.m_long = S_IFDIR; - udsentry.append(udsatom); - break; - - case SMBURLTYPE_SHARE_OR_PATH: - if (browse_stat_path(m_current_url, udsentry, false)) - break; - else { - kdDebug(KIO_SMB) << "SMBSlave::stat ERROR!!"<< endl; - finished(); - return; - } - default: - kdDebug(KIO_SMB) << "SMBSlave::stat UNKNOWN " << url << endl; - finished(); - return; - } - - statEntry(udsentry); - finished(); -} - -//=========================================================================== -// TODO: complete checking -KURL SMBSlave::checkURL(const KURL& kurl) const -{ - kdDebug(KIO_SMB) << "checkURL " << kurl << endl; - TQString surl = kurl.url(); - if (surl.startsWith("smb:/")) { - if (surl.length() == 5) // just the above - return kurl; // unchanged - - if (surl.at(5) != '/') { - surl = "smb://" + surl.mid(5); - kdDebug(KIO_SMB) << "checkURL return1 " << surl << " " << KURL(surl) << endl; - return KURL(surl); - } - } - - // smb:/ normaly have no userinfo - // we must redirect ourself to remove the username and password - if (surl.contains('@') && !surl.contains("smb://")) { - KURL url(kurl); - url.setPath("/"+kurl.url().right( kurl.url().length()-kurl.url().find('@') -1)); - TQString userinfo = kurl.url().mid(5, kurl.url().find('@')-5); - if(userinfo.contains(':')) { - url.setUser(userinfo.left(userinfo.find(':'))); - url.setPass(userinfo.right(userinfo.length()-userinfo.find(':')-1)); - } else { - url.setUser(userinfo); - } - kdDebug(KIO_SMB) << "checkURL return2 " << url << endl; - return url; - } - - // no emtpy path - KURL url(kurl); - - if (url.path().isEmpty()) - url.setPath("/"); - - kdDebug(KIO_SMB) << "checkURL return3 " << url << endl; - return url; -} - -void SMBSlave::reportError(const SMBUrl &url) -{ - kdDebug(KIO_SMB) << "reportError " << url << " " << perror << endl; - switch(errno) - { - case ENOENT: - if (url.getType() == SMBURLTYPE_ENTIRE_NETWORK) - error( ERR_SLAVE_DEFINED, i18n("Unable to find any workgroups in your local network. This might be caused by an enabled firewall.")); - else - error( ERR_DOES_NOT_EXIST, url.prettyURL()); - break; -#ifdef ENOMEDIUM - case ENOMEDIUM: - error( ERR_SLAVE_DEFINED, - i18n( "No media in device for %1" ).arg( url.prettyURL() ) ); - break; -#endif -#ifdef EHOSTDOWN - case EHOSTDOWN: -#endif - case ECONNREFUSED: - error( ERR_SLAVE_DEFINED, - i18n( "Could not connect to host for %1" ).arg( url.prettyURL() ) ); - break; - case ENOTDIR: - error( ERR_CANNOT_ENTER_DIRECTORY, url.prettyURL()); - break; - case EFAULT: - case EINVAL: - error( ERR_DOES_NOT_EXIST, url.prettyURL()); - break; - case EPERM: - case EACCES: - error( ERR_ACCESS_DENIED, url.prettyURL() ); - break; - case EIO: - case ENETUNREACH: - if ( url.getType() == SMBURLTYPE_ENTIRE_NETWORK || url.getType() == SMBURLTYPE_WORKGROUP_OR_SERVER ) - error( ERR_SLAVE_DEFINED, i18n( "Error while connecting to server responsible for %1" ).arg( url.prettyURL() ) ); - else - error( ERR_CONNECTION_BROKEN, url.prettyURL()); - break; - case ENOMEM: - error( ERR_OUT_OF_MEMORY, url.prettyURL() ); - break; - case ENODEV: - error( ERR_SLAVE_DEFINED, i18n("Share could not be found on given server")); - break; - case EBADF: - error( ERR_INTERNAL, i18n("BAD File descriptor")); - break; - case ETIMEDOUT: - error( ERR_SERVER_TIMEOUT, url.host() ); - break; -#ifdef ENOTUNIQ - case ENOTUNIQ: - error( ERR_SLAVE_DEFINED, i18n( "The given name could not be resolved to a unique server. " - "Make sure your network is setup without any name conflicts " - "between names used by Windows and by UNIX name resolution." ) ); - break; -#endif - case 0: // success - error( ERR_INTERNAL, i18n("libsmbclient reported an error, but did not specify " - "what the problem is. This might indicate a severe problem " - "with your network - but also might indicate a problem with " - "libsmbclient.\n" - "If you want to help us, please provide a tcpdump of the " - "network interface while you try to browse (be aware that " - "it might contain private data, so do not post it if you are " - "unsure about that - you can send it privately to the developers " - "if they ask for it)") ); - break; - default: - error( ERR_INTERNAL, i18n("Unknown error condition in stat: %1").arg(TQString::fromLocal8Bit( strerror(errno))) ); - } -} - -//=========================================================================== -void SMBSlave::listDir( const KURL& kurl ) -{ - kdDebug(KIO_SMB) << "SMBSlave::listDir on " << kurl << endl; - - // check (correct) URL - KURL url = checkURL(kurl); - // if URL is not valid we have to redirect to correct URL - if (url != kurl) - { - redirection(url); - finished(); - return; - } - - m_current_url = kurl; - - int dirfd; - struct smbc_dirent *dirp = NULL; - UDSEntry udsentry; - UDSAtom atom; - - dirfd = smbc_opendir( m_current_url.toSmbcUrl() ); - kdDebug(KIO_SMB) << "SMBSlave::listDir open " << m_current_url.toSmbcUrl() << " " << m_current_url.getType() << " " << dirfd << endl; - if(dirfd >= 0) - { - do { - kdDebug(KIO_SMB) << "smbc_readdir " << endl; - dirp = smbc_readdir(dirfd); - if(dirp == 0) - break; - - // Set name - atom.m_uds = TDEIO::UDS_NAME; - TQString dirpName = TQString::fromUtf8( dirp->name ); - // We cannot trust dirp->commentlen has it might be with or without the NUL character - // See KDE bug #111430 and Samba bug #3030 - TQString comment = TQString::fromUtf8( dirp->comment ); - if ( dirp->smbc_type == SMBC_SERVER || dirp->smbc_type == SMBC_WORKGROUP ) { - atom.m_str = dirpName.lower(); - atom.m_str.at( 0 ) = dirpName.at( 0 ).upper(); - if ( !comment.isEmpty() && dirp->smbc_type == SMBC_SERVER ) - atom.m_str += " (" + comment + ")"; - } else - atom.m_str = dirpName; - - kdDebug(KIO_SMB) << "dirp->name " << dirp->name << " " << dirpName << " '" << comment << "'" << " " << dirp->smbc_type << endl; - - udsentry.append( atom ); - if (atom.m_str.upper()=="IPC$" || atom.m_str=="." || atom.m_str == ".." || - atom.m_str.upper() == "ADMIN$" || atom.m_str.lower() == "printer$" || atom.m_str.lower() == "print$" ) - { -// fprintf(stderr,"----------- hide: -%s-\n",dirp->name); - // do nothing and hide the hidden shares - } - else if(dirp->smbc_type == SMBC_FILE) - { - // Set stat information - m_current_url.addPath(dirpName); - browse_stat_path(m_current_url, udsentry, true); - m_current_url.cd(".."); - - // Call base class to list entry - listEntry(udsentry, false); - } - else if(dirp->smbc_type == SMBC_DIR) - { - m_current_url.addPath(dirpName); - browse_stat_path(m_current_url, udsentry, true); - m_current_url.cd(".."); - - // Call base class to list entry - listEntry(udsentry, false); - } - else if(dirp->smbc_type == SMBC_SERVER || - dirp->smbc_type == SMBC_FILE_SHARE) - { - // Set type - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - udsentry.append( atom ); - - // Set permissions - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = (S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH); - udsentry.append(atom); - - if (dirp->smbc_type == SMBC_SERVER) { - atom.m_uds = TDEIO::UDS_URL; - // TQString workgroup = m_current_url.host().upper(); - KURL u("smb:/"); - u.setHost(dirpName); - atom.m_str = u.url(); - - // when libsmbclient knows - // atom.m_str = TQString("smb://%1?WORKGROUP=%2").arg(dirpName).arg(workgroup.upper()); - kdDebug(KIO_SMB) << "list item " << atom.m_str << endl; - udsentry.append(atom); - - atom.m_uds = TDEIO::UDS_MIME_TYPE; - atom.m_str = TQString::fromLatin1("application/x-smb-server"); - udsentry.append(atom); - } - - // Call base class to list entry - listEntry(udsentry, false); - } - else if(dirp->smbc_type == SMBC_WORKGROUP) - { - // Set type - atom.m_uds = TDEIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - udsentry.append( atom ); - - // Set permissions - atom.m_uds = TDEIO::UDS_ACCESS; - atom.m_long = (S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH); - udsentry.append(atom); - - atom.m_uds = TDEIO::UDS_MIME_TYPE; - atom.m_str = TQString::fromLatin1("application/x-smb-workgroup"); - udsentry.append(atom); - - atom.m_uds = TDEIO::UDS_URL; - // TQString workgroup = m_current_url.host().upper(); - KURL u("smb:/"); - u.setHost(dirpName); - atom.m_str = u.url(); - udsentry.append(atom); - - // Call base class to list entry - listEntry(udsentry, false); - } - else - { - kdDebug(KIO_SMB) << "SMBSlave::listDir SMBC_UNKNOWN :" << dirpName << endl; - // TODO: we don't handle SMBC_IPC_SHARE, SMBC_PRINTER_SHARE - // SMBC_LINK, SMBC_COMMS_SHARE - //SlaveBase::error(ERR_INTERNAL, TEXT_UNSUPPORTED_FILE_TYPE); - // continue; - } - udsentry.clear(); - } while (dirp); // checked already in the head - - // clean up - smbc_closedir(dirfd); - } - else - { - if (errno == EPERM || errno == EACCES) - if (checkPassword(m_current_url)) { - redirection( m_current_url ); - finished(); - return; - } - - reportError(m_current_url); - finished(); - return; - } - - listEntry(udsentry, true); - finished(); -} - diff --git a/tdeioslave/smb/kio_smb_config.cpp b/tdeioslave/smb/kio_smb_config.cpp deleted file mode 100644 index 8179371e7..000000000 --- a/tdeioslave/smb/kio_smb_config.cpp +++ /dev/null @@ -1,66 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_config.cpp -// -// Abstract: member function implementations for SMBSlave that deal with -// KDE/SMB slave configuration -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include "kio_smb.h" -#include "kio_smb_internal.h" -#include - -#include -//=========================================================================== -void SMBSlave::reparseConfiguration() -{ - TDEConfig *cfg = new TDEConfig("tdeioslaverc", true); - cfg->setGroup("Browser Settings/SMBro"); - m_default_user=cfg->readEntry("User"); -// m_default_workgroup=cfg->readEntry("Workgroup"); -// m_showHiddenShares=cfg->readBoolEntry("ShowHiddenShares",false); - - TQString m_encoding = TQTextCodec::codecForLocale()->name(); - m_default_encoding = cfg->readEntry( "Encoding", m_encoding.lower() ); - - // unscramble, taken from Nicola Brodu's smb ioslave - //not really secure, but better than storing the plain password - TQString scrambled = cfg->readEntry( "Password" ); - m_default_password = ""; - for (uint i=0; i -// -////--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include "kio_smb.h" -#include "kio_smb_internal.h" - - -//=========================================================================== -// TODO: add when libsmbclient supports it -void SMBSlave::copy( const KURL& ksrc, - const KURL& kdst, - int permissions, - bool overwrite) -{ - - SMBUrl src; - SMBUrl dst; - mode_t initialmode; - int n; - int dstflags; - int srcfd = -1; - int dstfd = -1; - TDEIO::filesize_t processed_size = 0; - unsigned char buf[MAX_XFER_BUF_SIZE]; - - kdDebug(KIO_SMB) << "SMBSlave::copy with src = " << ksrc << "and dest = " << kdst << endl; - - // setup urls - src = ksrc; - dst = kdst; - - // Obtain information about source - if(cache_stat(src, &st ) == -1) - { - if ( errno == EACCES ) - { - error( TDEIO::ERR_ACCESS_DENIED, src.prettyURL()); - } - else - { - error( TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL()); - } - return; - } - if ( S_ISDIR( st.st_mode ) ) - { - error( TDEIO::ERR_IS_DIRECTORY, src.prettyURL() ); - return; - } - totalSize(st.st_size); - - // Check to se if the destination exists - if(cache_stat(dst, &st) != -1) - { - if(S_ISDIR(st.st_mode)) - { - error( TDEIO::ERR_DIR_ALREADY_EXIST, dst.prettyURL()); - return; - } - if(!overwrite) - { - error( TDEIO::ERR_FILE_ALREADY_EXIST, dst.prettyURL()); - return; - } - } - - // Open the source file - srcfd = smbc_open(src.toSmbcUrl(), O_RDONLY, 0); - if(srcfd < 0) - { - if(errno == EACCES) - { - error( TDEIO::ERR_ACCESS_DENIED, src.prettyURL() ); - } - else - { - error( TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL() ); - } - return; - } - - // Determine initial creation mode - if(permissions != -1) - { - initialmode = permissions | S_IWUSR; - } - else - { - initialmode = 0 | S_IWUSR;//0666; - } - - - // Open the destination file - dstflags = O_CREAT | O_TRUNC | O_WRONLY; - if(!overwrite) - { - dstflags |= O_EXCL; - } - dstfd = smbc_open(dst.toSmbcUrl(), dstflags, initialmode); - if(dstfd < 0) - { - if(errno == EACCES) - { - error(TDEIO::ERR_WRITE_ACCESS_DENIED, dst.prettyURL()); - } - else - { - error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, dst.prettyURL()); - } - if(srcfd >= 0 ) - { - smbc_close(srcfd); - } - return; - } - - - // Perform copy - while(1) - { - n = smbc_read(srcfd, buf, MAX_XFER_BUF_SIZE ); - if(n > 0) - { - n = smbc_write(dstfd, buf, n); - if(n == -1) - { - kdDebug(KIO_SMB) << "SMBSlave::copy copy now TDEIO::ERR_COULD_NOT_WRITE" << endl; - error( TDEIO::ERR_COULD_NOT_WRITE, dst.prettyURL()); - break; - } - - processed_size += n; - processedSize(processed_size); - } - else if(n == 0) - { - break; // finished - } - else - { - error( TDEIO::ERR_COULD_NOT_READ, src.prettyURL()); - break; - } - } - - - // FINISHED: - - if(srcfd >= 0 ) - { - smbc_close(srcfd); - } - - if(dstfd >= 0) - { - if(smbc_close(dstfd) == 0) - { - - // TODO: set final permissions - } - else - { - error( TDEIO::ERR_COULD_NOT_WRITE, dst.prettyURL()); - return; - } - } - - finished(); -} - -//=========================================================================== -void SMBSlave::del( const KURL &kurl, bool isfile) -{ - kdDebug(KIO_SMB) << "SMBSlave::del on " << kurl << endl; - m_current_url = kurl; - - if(isfile) - { - // Delete file - kdDebug(KIO_SMB) << "SMBSlave:: unlink " << kurl << endl; - if(smbc_unlink(m_current_url.toSmbcUrl()) == -1) - { - switch(errno) - { - case EISDIR: - error( TDEIO::ERR_IS_DIRECTORY, m_current_url.prettyURL()); - break; - default: - reportError(kurl); - } - } - } - else - { - kdDebug(KIO_SMB) << "SMBSlave:: rmdir " << kurl << endl; - // Delete directory - if(smbc_rmdir(m_current_url.toSmbcUrl()) == -1) - { - reportError(kurl); - } - } - - finished(); -} - -//=========================================================================== -void SMBSlave::mkdir( const KURL &kurl, int permissions ) -{ - kdDebug(KIO_SMB) << "SMBSlave::mkdir on " << kurl << endl; - m_current_url = kurl; - - if(smbc_mkdir(m_current_url.toSmbcUrl(), 0777) != 0) - { - if (errno == EEXIST) { - if(cache_stat(m_current_url, &st ) == 0) - { - if(S_ISDIR(st.st_mode )) - { - error( TDEIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL()); - } - } - else - { - error( TDEIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL()); - } - } else - reportError(kurl); - kdDebug(KIO_SMB) << "SMBSlave::mkdir exit with error " << kurl << endl; - } - else - { - if(permissions != -1) - { - // TODO enable the following when complete - //smbc_chmod( url.toSmbcUrl(), permissions ); - } - } - - finished(); -} - - -//=========================================================================== -void SMBSlave::rename( const KURL& ksrc, const KURL& kdest, bool overwrite ) -{ - - SMBUrl src; - SMBUrl dst; - - kdDebug(KIO_SMB) << "SMBSlave::rename, old name = " << ksrc << ", new name = " << kdest << endl; - - src = ksrc; - dst = kdest; - - // Check to se if the destination exists - - kdDebug(KIO_SMB) << "SMBSlave::rename stat dst" << endl; - if(cache_stat(dst, &st) != -1) - { - if(S_ISDIR(st.st_mode)) - { - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_DIR_ALREADY_EXIST" << endl; - error( TDEIO::ERR_DIR_ALREADY_EXIST, dst.prettyURL()); - finished(); - return; - } - if(!overwrite) - { - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_FILE_ALREADY_EXIST" << endl; - error( TDEIO::ERR_FILE_ALREADY_EXIST, dst.prettyURL()); - finished(); - return; - } - } - kdDebug(KIO_SMB ) << "smbc_rename " << src.toSmbcUrl() << " " << dst.toSmbcUrl() << endl; - if(smbc_rename(src.toSmbcUrl(), dst.toSmbcUrl())!=0) - { - kdDebug(KIO_SMB ) << "failed " << perror << endl; - switch(errno) - { - case ENOENT: - if(cache_stat(src, &st) == -1) - { - if(errno == EACCES) - { - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_ACCESS_DENIED" << endl; - error(TDEIO::ERR_ACCESS_DENIED, src.prettyURL()); - } - else - { - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_DOES_NOT_EXIST" << endl; - error(TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL()); - } - } - break; - - case EACCES: - case EPERM: - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_ACCESS_DENIED" << endl; - error( TDEIO::ERR_ACCESS_DENIED, dst.prettyURL() ); - break; - - default: - kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_CANNOT_RENAME" << endl; - error( TDEIO::ERR_CANNOT_RENAME, src.prettyURL() ); - - } - - kdDebug(KIO_SMB) << "SMBSlave::rename exit with error" << endl; - return; - } - - kdDebug(KIO_SMB ) << "everything fine\n"; - finished(); -} - - diff --git a/tdeioslave/smb/kio_smb_file.cpp b/tdeioslave/smb/kio_smb_file.cpp deleted file mode 100644 index b65f79f42..000000000 --- a/tdeioslave/smb/kio_smb_file.cpp +++ /dev/null @@ -1,279 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_file.cpp -// -// Abstract: member function implementations for SMBSlave that deal with -// SMB file access -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - - -#include "kio_smb.h" -#include "kio_smb_internal.h" - -#include - -//=========================================================================== -void SMBSlave::get( const KURL& kurl ) -{ - char buf[MAX_XFER_BUF_SIZE]; - int filefd = 0; - ssize_t bytesread = 0; - // time_t curtime = 0; - time_t lasttime = 0; - time_t starttime = 0; - TDEIO::filesize_t totalbytesread = 0; - TQByteArray filedata; - SMBUrl url; - - kdDebug(KIO_SMB) << "SMBSlave::get on " << kurl << endl; - - // check (correct) URL - KURL kvurl = checkURL(kurl); - // if URL is not valid we have to redirect to correct URL - if (kvurl != kurl) { - redirection(kvurl); - finished(); - return; - } - - if(!auth_initialize_smbc()) - return; - - - // Stat - url = kurl; - if(cache_stat(url,&st) == -1 ) - { - if ( errno == EACCES ) - error( TDEIO::ERR_ACCESS_DENIED, url.prettyURL()); - else - error( TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - return; - } - if ( S_ISDIR( st.st_mode ) ) { - error( TDEIO::ERR_IS_DIRECTORY, url.prettyURL()); - return; - } - - // Set the total size - totalSize( st.st_size ); - - // Open and read the file - filefd = smbc_open(url.toSmbcUrl(),O_RDONLY,0); - if(filefd >= 0) - { - if(buf) - { - bool isFirstPacket = true; - lasttime = starttime = time(NULL); - while(1) - { - bytesread = smbc_read(filefd, buf, MAX_XFER_BUF_SIZE); - if(bytesread == 0) - { - // All done reading - break; - } - else if(bytesread < 0) - { - error( TDEIO::ERR_COULD_NOT_READ, url.prettyURL()); - return; - } - - filedata.setRawData(buf,bytesread); - if (isFirstPacket) - { - // We need a KMimeType::findByNameAndContent(filename,data) - // For now we do: find by extension, and if not found (or extension not reliable) - // then find by content. - bool accurate = false; - KMimeType::Ptr mime = KMimeType::findByURL( kurl, st.st_mode, false, true, &accurate ); - if ( !mime || mime->name() == KMimeType::defaultMimeType() - || !accurate ) - { - KMimeType::Ptr p_mimeType = KMimeType::findByContent(filedata); - if ( p_mimeType && p_mimeType->name() != KMimeType::defaultMimeType() ) - mime = p_mimeType; - } - mimeType(mime->name()); - isFirstPacket = false; - } - data( filedata ); - filedata.resetRawData(buf,bytesread); - - // increment total bytes read - totalbytesread += bytesread; - - processedSize(totalbytesread); - } - } - - smbc_close(filefd); - data( TQByteArray() ); - processedSize(static_cast(st.st_size)); - - } - else - { - error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); - return; - } - - finished(); -} - - -//=========================================================================== -void SMBSlave::put( const KURL& kurl, - int permissions, - bool overwrite, - bool resume ) -{ - - void *buf; - size_t bufsize; - - m_current_url = kurl; - - int filefd; - bool exists; - mode_t mode; - TQByteArray filedata; - - kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl << endl; - - - exists = (cache_stat(m_current_url, &st) != -1 ); - if ( exists && !overwrite && !resume) - { - if (S_ISDIR(st.st_mode)) - { - kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already isdir !!"<< endl; - error( TDEIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL()); - } - else - { - kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already exist !!"<< endl; - error( TDEIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL()); - } - return; - } - - if (exists && !resume && overwrite) - { - kdDebug(KIO_SMB) << "SMBSlave::put exists try to remove " << m_current_url.toSmbcUrl()<< endl; - // remove(m_current_url.url().local8Bit()); - } - - - if (resume) - { - // append if resuming - kdDebug(KIO_SMB) << "SMBSlave::put resume " << m_current_url.toSmbcUrl()<< endl; - filefd = smbc_open(m_current_url.toSmbcUrl(), O_RDWR, 0 ); - smbc_lseek(filefd, 0, SEEK_END); - } - else - { - if (permissions != -1) - { - mode = permissions | S_IWUSR | S_IRUSR; - } - else - { - mode = 600;//0666; - } - - kdDebug(KIO_SMB) << "SMBSlave::put NO resume " << m_current_url.toSmbcUrl()<< endl; - filefd = smbc_open(m_current_url.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode); - } - - if ( filefd < 0 ) - { - if ( errno == EACCES ) - { - kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" access denied !!"<< endl; - error( TDEIO::ERR_WRITE_ACCESS_DENIED, m_current_url.prettyURL()); - } - else - { - kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" can not open for writing !!"<< endl; - error( TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, m_current_url.prettyURL()); - } - finished(); - return; - } - - // Loop until we got 0 (end of data) - while(1) - { - kdDebug(KIO_SMB) << "SMBSlave::put request data "<< endl; - dataReq(); // Request for data - kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; - - if (readData(filedata) <= 0) - { - kdDebug(KIO_SMB) << "readData <= 0" << endl; - break; - } - kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; - buf = filedata.data(); - bufsize = filedata.size(); - int size = smbc_write(filefd, buf, bufsize); - if ( size < 0) - { - kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" could not write !!"<< endl; - error( TDEIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); - finished(); - return; - } - kdDebug(KIO_SMB ) << "wrote " << size << endl; - } - kdDebug(KIO_SMB) << "SMBSlave::put close " << m_current_url.toSmbcUrl()<< endl; - - if(smbc_close(filefd)) - { - kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" could not write !!"<< endl; - error( TDEIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); - finished(); - return; - } - - // set final permissions, if the file was just created - if ( permissions != -1 && !exists ) - { - // TODO: did the smbc_chmod fail? - // TODO: put in call to chmod when it is working! - // smbc_chmod(url.toSmbcUrl(),permissions); - } - - // We have done our job => finish - finished(); -} - - - - diff --git a/tdeioslave/smb/kio_smb_internal.cpp b/tdeioslave/smb/kio_smb_internal.cpp deleted file mode 100644 index 8f56a8f62..000000000 --- a/tdeioslave/smb/kio_smb_internal.cpp +++ /dev/null @@ -1,135 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_internal.cpp -// -// Abstract: Utility class implementation used by SMBSlave -// -// Author(s): Matthew Peterson -// -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#include "kio_smb.h" -#include "kio_smb_internal.h" - -#include - -#include -#include - - -//=========================================================================== -// SMBUrl Function Implementation -//=========================================================================== - -//----------------------------------------------------------------------- -SMBUrl::SMBUrl() -{ - m_type = SMBURLTYPE_UNKNOWN; -} - -//----------------------------------------------------------------------- -SMBUrl::SMBUrl(const KURL& kurl) - : KURL(kurl) - //----------------------------------------------------------------------- -{ - updateCache(); -} - - -//----------------------------------------------------------------------- -void SMBUrl::addPath(const TQString &filedir) -{ - KURL::addPath(filedir); - updateCache(); -} - -//----------------------------------------------------------------------- -bool SMBUrl::cd(const TQString &filedir) -{ - if (!KURL::cd(filedir)) - return false; - updateCache(); - return true; -} - -//----------------------------------------------------------------------- -void SMBUrl::updateCache() - //----------------------------------------------------------------------- -{ - cleanPath(); - - // SMB URLs are UTF-8 encoded - kdDebug(KIO_SMB) << "updateCache " << KURL::path() << endl; - if (KURL::url() == "smb:/") - m_surl = "smb://"; - else { - TQString surl = "smb://"; - if (KURL::hasUser()) { - surl += KURL::encode_string(KURL::user(), 106); - if (KURL::hasPass()) { - surl += ":" + KURL::encode_string(KURL::pass(), 106); - } - surl += "@"; - } - surl += KURL::encode_string(KURL::host().upper(), 106); - surl += KURL::encode_string(KURL::path(), 106); - m_surl = surl.utf8(); - } - m_type = SMBURLTYPE_UNKNOWN; - // update m_type - (void)getType(); -} - -//----------------------------------------------------------------------- -SMBUrlType SMBUrl::getType() const - // Returns the type of this SMBUrl: - // SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. - // SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network - // SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" - // SMBURLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" - //----------------------------------------------------------------------- -{ - if(m_type != SMBURLTYPE_UNKNOWN) - return m_type; - - if (protocol() != "smb") - { - m_type = SMBURLTYPE_UNKNOWN; - return m_type; - } - - if (path(1) == "/") - { - if (host().isEmpty()) - m_type = SMBURLTYPE_ENTIRE_NETWORK; - else - m_type = SMBURLTYPE_WORKGROUP_OR_SERVER; - return m_type; - } - - // Check for the path if we get this far - m_type = SMBURLTYPE_SHARE_OR_PATH; - - return m_type; -} - diff --git a/tdeioslave/smb/kio_smb_internal.h b/tdeioslave/smb/kio_smb_internal.h deleted file mode 100644 index 2d97aee31..000000000 --- a/tdeioslave/smb/kio_smb_internal.h +++ /dev/null @@ -1,118 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Project: SMB tdeioslave for KDE2 -// -// File: kio_smb_internal.h -// -// Abstract: Utility classes used by SMBSlave -// -// Author(s): Matthew Peterson -// Frank Schwanz -//--------------------------------------------------------------------------- -// -// Copyright (c) 2000 Caldera Systems, Inc. -// -// 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; either version 2.1 of the License, or -// (at your option) any later version. -// -// 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 Lesser 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, please obtain -// a copy from http://www.gnu.org/copyleft/gpl.html -// -///////////////////////////////////////////////////////////////////////////// - -#ifndef KIO_SMB_INTERNAL_H_INCLUDED -#define KIO_SMB_INTERNAL_H_INCLUDED - -#include - -/** - * Types of a SMBURL : - * SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. - * SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network - * SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" - * URLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" - */ -enum SMBUrlType { - SMBURLTYPE_UNKNOWN = 0, SMBURLTYPE_ENTIRE_NETWORK = 1, - SMBURLTYPE_WORKGROUP_OR_SERVER = 2, SMBURLTYPE_SHARE_OR_PATH = 3 -}; - - -//=========================================================================== -/** - * Class to handle URL's - * it can convert KURL to smbUrl - * and Handle UserInfo - * it also check the correctness of the URL - */ -class SMBUrl : public KURL -{ - - -public: - SMBUrl(); - SMBUrl(const KURL & kurl); - - /** - * Appends the specified file and dir to this SMBUrl - * "smb://server/share" --> "smb://server/share/filedir" - */ - void addPath(const TQString &filedir); - - bool cd(const TQString &dir); - - /** - * Returns the type of this SMBUrl: - * SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. - * SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network - * SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" - * URLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" - */ - SMBUrlType getType() const; - - void setPass( const TQString& _txt ) { KURL::setPass(_txt); updateCache(); } - void setUser( const TQString& _txt ) { KURL::setUser(_txt); updateCache(); } - void setHost( const TQString& _txt ) { KURL::setHost(_txt); updateCache(); } - - /** - * Returns the workgroup if it given in url - */ -// TQString getWorkgroup() const; - - /** - * Returns path after workgroup - */ -// TQString getServerShareDir() const; - - /** - * Return a URL that is suitable for libsmbclient - */ - TQCString toSmbcUrl() const { return m_surl; } - -private: - /** - * Change from TQString to TQCString (MS Windows's character encoding) - */ - TQCString fromUnicode( const TQString &_str ) const; - - void updateCache(); - TQCString m_surl; - - /** - * Type of URL - * @see _SMBUrlType - */ - mutable SMBUrlType m_type; -}; - - -#endif - diff --git a/tdeioslave/smb/kio_smb_mount.cpp b/tdeioslave/smb/kio_smb_mount.cpp deleted file mode 100644 index ad421f631..000000000 --- a/tdeioslave/smb/kio_smb_mount.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* This file is part of the KDE project - - Copyright (C) 2000 Alexander Neundorf - - 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_smb.h" -#include -#include -#include -#include -#include - -void SMBSlave::readOutput(TDEProcess *, char *buffer, int buflen) -{ - mybuf += TQString::fromLocal8Bit(buffer, buflen); -} - -void SMBSlave::readStdErr(TDEProcess *, char *buffer, int buflen) -{ - mystderr += TQString::fromLocal8Bit(buffer, buflen); -} - -void SMBSlave::special( const TQByteArray & data) -{ - kdDebug(KIO_SMB)<<"Smb::special()"<> tmp; - //mounting and umounting are both blocking, "guarded" by a SIGALARM in the future - switch (tmp) - { - case 1: - case 3: - { - TQString remotePath, mountPoint, user; - stream >> remotePath >> mountPoint; - - TQStringList sl=TQStringList::split("/",remotePath); - TQString share,host; - if (sl.count()>=2) - { - host=(*sl.at(0)).mid(2); - share=(*sl.at(1)); - kdDebug(KIO_SMB)<<"special() host -"<< host <<"- share -" << share <<"-"<> mountPoint; - - TDEProcess proc; - proc.setUseShell(true); - proc << "smbumount"; - proc << TDEProcess::quote(mountPoint); - - mybuf.truncate(0); - mystderr.truncate(0); - - connect(&proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int )), - TQT_SLOT(readOutput(TDEProcess *, char *, int))); - - connect(&proc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int )), - TQT_SLOT(readStdErr(TDEProcess *, char *, int))); - - if ( !proc.start( TDEProcess::Block, TDEProcess::AllOutput ) ) - { - error(TDEIO::ERR_CANNOT_LAUNCH_PROCESS, - "smbumount"+i18n("\nMake sure that the samba package is installed properly on your system.")); - return; - } - - kdDebug(KIO_SMB) << "smbumount exit " << proc.exitStatus() << endl - << "stdout:" << mybuf << endl << "stderr:" << mystderr << endl; - - if (proc.exitStatus() != 0) - { - error(TDEIO::ERR_COULD_NOT_UNMOUNT, - i18n("Unmounting of mountpoint \"%1\" failed.\n%2") - .arg(mountPoint).arg(mybuf + "\n" + mystderr)); - return; - } - - if ( tmp == 4 ) - { - bool ok; - - TQDir dir(mountPoint); - dir.cdUp(); - ok = dir.rmdir(mountPoint); - if ( ok ) - { - TQString p=dir.path(); - dir.cdUp(); - ok = dir.rmdir(p); - } - - if ( !ok ) - { - error(TDEIO::ERR_COULD_NOT_RMDIR, mountPoint); - return; - } - } - - finished(); - } - break; - default: - break; - } - finished(); -} - -#include "kio_smb.moc" diff --git a/tdeioslave/smb/smb.protocol b/tdeioslave/smb/smb.protocol index 2c0bda020..06ac69a10 100644 --- a/tdeioslave/smb/smb.protocol +++ b/tdeioslave/smb/smb.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_smb +exec=tdeio_smb protocol=smb input=none output=filesystem diff --git a/tdeioslave/smb/tdeio_smb.cpp b/tdeioslave/smb/tdeio_smb.cpp new file mode 100644 index 000000000..8ee270256 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb.cpp @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: Top level implementation file for tdeio_smb.cpp +// +// Abstract: member function implementations for SMBSlave +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + +//=========================================================================== +SMBSlave::SMBSlave(const TQCString& pool, const TQCString& app) + : SlaveBase( "smb", pool, app ) +{ + m_initialized_smbc = false; + + //read in the default workgroup info... + reparseConfiguration(); + + //initialize the library... + auth_initialize_smbc(); +} + + +//=========================================================================== +SMBSlave::~SMBSlave() +{ +} + + +//=========================================================================== +// pointer to the slave created in kdemain +SMBSlave* G_TheSlave; + +//=========================================================================== +int KDE_EXPORT kdemain( int argc, char **argv ) +{ + + TDEInstance instance( "tdeio_smb" ); + if( argc != 4 ) + { + kdDebug(KIO_SMB) << "Usage: tdeio_smb protocol domain-socket1 domain-socket2" + << endl; + return -1; + } + + SMBSlave slave( argv[2], argv[3] ); + + G_TheSlave = &slave; + slave.dispatchLoop(); + + return 0; +} + diff --git a/tdeioslave/smb/tdeio_smb.h b/tdeioslave/smb/tdeio_smb.h new file mode 100644 index 000000000..0c89eae95 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb.h @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb.h +// +// Abstract: The main tdeio slave class declaration. For convenience, +// in concurrent devlopment, the implementation for this class +// is separated into several .cpp files -- the file containing +// the implementation should be noted in the comments for each +// member function. +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + + +#ifndef KIO_SMB_H_INCLUDED +#define KIO_SMB_H_INCLUDED + +//------------- +// QT includes +//------------- +#include +#include +#include +#include +#include + +//-------------- +// KDE includes +//-------------- +#include +#include +#include +#include +#include +#include + +//----------------------------- +// Standard C library includes +//----------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------- +// Samba client library includes +//------------------------------- +extern "C" +{ +#include +} + +//--------------------------- +// tdeio_smb internal includes +//--------------------------- +#include "tdeio_smb_internal.h" + +#define MAX_XFER_BUF_SIZE 16348 +#define KIO_SMB 7106 + +using namespace TDEIO; +class TDEProcess; + +//=========================================================================== + + +class SMBSlave : public TQObject, public TDEIO::SlaveBase +{ + Q_OBJECT + +private: + //--------------------------------------------------------------------- + // please make sure your private data does not duplicate existing data + //--------------------------------------------------------------------- + bool m_initialized_smbc; + + /** + * From Controlcenter + */ + TQString m_default_user; +// TQString m_default_workgroup; //currently unused, Alex + TQString m_default_password; + TQString m_default_encoding; + + /** + * we store the current url, it's needed for + * callback authorisation method + */ + SMBUrl m_current_url; + + /** + * From Controlcenter, show SHARE$ or not + */ +// bool m_showHiddenShares; //currently unused, Alex + + /** + * libsmbclient need global variables to store in, + * else it crashes on exit next method after use cache_stat, + * looks like gcc (C/C++) failure + */ + struct stat st; +protected: + //--------------------------------------------- + // Authentication functions (tdeio_smb_auth.cpp) + //--------------------------------------------- + // (please prefix functions with auth) + + + /** + * Description : Initilizes the libsmbclient + * Return : true on success false with errno set on error + */ + bool auth_initialize_smbc(); + + bool checkPassword(SMBUrl &url); + + + //--------------------------------------------- + // Cache functions (tdeio_smb_auth.cpp) + //--------------------------------------------- + + //Stat methods + + //----------------------------------------- + // Browsing functions (tdeio_smb_browse.cpp) + //----------------------------------------- + // (please prefix functions with browse) + + /** + * Description : Return a stat of given SMBUrl. Calls cache_stat and + * pack it in UDSEntry. UDSEntry will not be cleared + * Parameter : SMBUrl the url to stat + * ignore_errors do not call error(), but warning() + * Return : false if any error occoured (errno), else true + */ + bool browse_stat_path(const SMBUrl& url, UDSEntry& udsentry, bool ignore_errors); + + /** + * Description : call smbc_stat and return stats of the url + * Parameter : SMBUrl the url to stat + * Return : stat* of the url + * Note : it has some problems with stat in method, looks like + * something leave(or removed) on the stack. If your + * method segfault on returning try to change the stat* + * variable + */ + int cache_stat( const SMBUrl& url, struct stat* st ); + + //--------------------------------------------- + // Configuration functions (tdeio_smb_config.cpp) + //--------------------------------------------- + // (please prefix functions with config) + + + //--------------------------------------- + // Directory functions (tdeio_smb_dir.cpp) + //--------------------------------------- + // (please prefix functions with dir) + + + //-------------------------------------- + // File IO functions (tdeio_smb_file.cpp) + //-------------------------------------- + // (please prefix functions with file) + + //---------------------------- + // Misc functions (this file) + //---------------------------- + + + /** + * Description : correct a given URL + * valid URL's are + * + * smb://[[domain;]user[:password]@]server[:port][/share[/path[/file]]] + * smb:/[[domain;]user[:password]@][group/[server[/share[/path[/file]]]]] + * domain = workgroup(domain) of the user + * user = username + * password = password of useraccount + * group = workgroup(domain) of server + * server = host to connect + * share = a share of the server (host) + * path = a path of the share + * Parameter : KURL the url to check + * Return : new KURL if its corrected. else the same KURL + */ + KURL checkURL(const KURL& kurl) const; + + void reportError(const SMBUrl &kurl); + +public: + + //----------------------------------------------------------------------- + // smbclient authentication callback (note that this is called by the + // global ::auth_smbc_get_data() call. + void auth_smbc_get_data(const char *server,const char *share, + char *workgroup, int wgmaxlen, + char *username, int unmaxlen, + char *password, int pwmaxlen); + + + //----------------------------------------------------------------------- + // Overwritten functions from the base class that define the operation of + // this slave. (See the base class headerfile slavebase.h for more + // details) + //----------------------------------------------------------------------- + + // Functions overwritten in tdeio_smb.cpp + SMBSlave(const TQCString& pool, const TQCString& app); + virtual ~SMBSlave(); + + // Functions overwritten in tdeio_smb_browse.cpp + virtual void listDir( const KURL& url ); + virtual void stat( const KURL& url ); + + // Functions overwritten in tdeio_smb_config.cpp + virtual void reparseConfiguration(); + + // Functions overwritten in tdeio_smb_dir.cpp + virtual void copy( const KURL& src, const KURL &dest, int permissions, bool overwrite ); + virtual void del( const KURL& kurl, bool isfile); + virtual void mkdir( const KURL& kurl, int permissions ); + virtual void rename( const KURL& src, const KURL& dest, bool overwrite ); + + // Functions overwritten in tdeio_smb_file.cpp + virtual void get( const KURL& kurl ); + virtual void put( const KURL& kurl, int permissions, bool overwrite, bool resume ); + + // Functions not implemented (yet) + //virtual void setHost(const TQString& host, int port, const TQString& user, const TQString& pass); + //virtual void openConnection(); + //virtual void closeConnection(); + //virtual void slave_status(); + virtual void special( const TQByteArray & ); + +private slots: + void readOutput(TDEProcess *proc, char *buffer, int buflen); + void readStdErr(TDEProcess *proc, char *buffer, int buflen); + +private: + TQString mybuf, mystderr; + +}; + +//=========================================================================== +// pointer to the slave created in kdemain +extern SMBSlave* G_TheSlave; + + +//========================================================================== +// the global libsmbclient authentication callback function +extern "C" +{ + +void auth_smbc_get_data(const char *server,const char *share, + char *workgroup, int wgmaxlen, + char *username, int unmaxlen, + char *password, int pwmaxlen); + +} + + +//=========================================================================== +// Main slave entrypoint (see tdeio_smb.cpp) +extern "C" +{ + +int kdemain( int argc, char **argv ); + +} + + +#endif //#endif KIO_SMB_H_INCLUDED diff --git a/tdeioslave/smb/tdeio_smb_auth.cpp b/tdeioslave/smb/tdeio_smb_auth.cpp new file mode 100644 index 000000000..ebc15c1c6 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_auth.cpp @@ -0,0 +1,207 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_auth.cpp +// +// Abstract: member function implementations for SMBSlave that deal with +// SMB directory access +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + +#include +#include +#include + +// call for libsmbclient +//========================================================================== +void auth_smbc_get_data(const char *server,const char *share, + char *workgroup, int wgmaxlen, + char *username, int unmaxlen, + char *password, int pwmaxlen) +//========================================================================== +{ + G_TheSlave->auth_smbc_get_data(server, share, + workgroup,wgmaxlen, + username, unmaxlen, + password, pwmaxlen); +} + +//-------------------------------------------------------------------------- +void SMBSlave::auth_smbc_get_data(const char *server,const char *share, + char *workgroup, int wgmaxlen, + char *username, int unmaxlen, + char *password, int pwmaxlen) +//-------------------------------------------------------------------------- +{ + //check this to see if we "really" need to authenticate... + SMBUrlType t = m_current_url.getType(); + if( t == SMBURLTYPE_ENTIRE_NETWORK ) + { + kdDebug(KIO_SMB) << "we don't really need to authenticate for this top level url, returning" << endl; + return; + } + kdDebug(KIO_SMB) << "AAAAAAAAAAAAAA auth_smbc_get_dat: set user=" << username << ", workgroup=" << workgroup + << " server=" << server << ", share=" << share << endl; + + TQString s_server = TQString::fromUtf8(server); + TQString s_share = TQString::fromUtf8(share); + workgroup[wgmaxlen - 1] = 0; + TQString s_workgroup = TQString::fromUtf8(workgroup); + username[unmaxlen - 1] = 0; + TQString s_username = TQString::fromUtf8(username); + password[pwmaxlen - 1] = 0; + TQString s_password = TQString::fromUtf8(password); + + TDEIO::AuthInfo info; + info.url = KURL("smb:///"); + info.url.setHost(s_server); + info.url.setPath("/" + s_share); + + info.username = s_username; + info.password = s_password; + info.verifyPath = true; + + kdDebug(KIO_SMB) << "libsmb-auth-callback URL:" << info.url << endl; + + if ( !checkCachedAuthentication( info ) ) + { + if ( m_default_user.isEmpty() ) + { + // ok, we do not know the password. Let's try anonymous before we try for real + info.username = "anonymous"; + info.password = TQString::null; + } + else + { + // user defined a default username/password in kcontrol; try this + info.username = m_default_user; + info.password = m_default_password; + } + + } else + kdDebug(KIO_SMB) << "got password through cache" << endl; + + strncpy(username, info.username.utf8(), unmaxlen - 1); + strncpy(password, info.password.utf8(), pwmaxlen - 1); +} + +bool SMBSlave::checkPassword(SMBUrl &url) +{ + kdDebug(KIO_SMB) << "checkPassword for " << url << endl; + + TDEIO::AuthInfo info; + info.url = KURL("smb:///"); + info.url.setHost(url.host()); + + TQString share = url.path(); + int index = share.find('/', 1); + if (index > 1) + share = share.left(index); + if (share.at(0) == '/') + share = share.mid(1); + info.url.setPath("/" + share); + info.verifyPath = true; + + if ( share.isEmpty() ) + info.prompt = i18n( + "Please enter authentication information for %1" ) + .arg( url.host() ); + else + info.prompt = i18n( + "Please enter authentication information for:\n" + "Server = %1\n" + "Share = %2" ) + .arg( url.host() ) + .arg( share ); + + info.username = url.user(); + kdDebug(KIO_SMB) << "call openPassDlg for " << info.url << endl; + + if ( openPassDlg(info) ) { + kdDebug(KIO_SMB) << "openPassDlg returned " << info.username << endl; + url.setUser(info.username); + url.setPass(info.password); + return true; + } + kdDebug(KIO_SMB) << "no value from openPassDlg\n"; + return false; +} + +//-------------------------------------------------------------------------- +// Initalizes the smbclient library +// +// Returns: 0 on success -1 with errno set on error +bool SMBSlave::auth_initialize_smbc() +{ + SMBCCTX *smb_context = NULL; + + kdDebug(KIO_SMB) << "auth_initialize_smbc " << endl; + if(m_initialized_smbc == false) + { + kdDebug(KIO_SMB) << "smbc_init call" << endl; + KSimpleConfig cfg( "tdeioslaverc", true ); + + cfg.setGroup( "SMB" ); + int debug_level = cfg.readNumEntry( "DebugLevel", 0 ); + +#if 0 + /* old API initialisation routine does not allow to set flags */ + + if(smbc_init(::auth_smbc_get_data,debug_level) == -1) + { + SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to initialize")); + return false; + } +#endif + smb_context = smbc_new_context(); + if (smb_context == NULL) { + SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to create context")); + return false; + } + + smb_context->debug = debug_level; + smb_context->callbacks.auth_fn = ::auth_smbc_get_data; + + if (!smbc_init_context(smb_context)) { + smbc_free_context(smb_context, false); + smb_context = NULL; + SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to initialize context")); + return false; + } + +#if defined(SMB_CTX_FLAG_USE_KERBEROS) && defined(SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) + smb_context->flags |= SMB_CTX_FLAG_USE_KERBEROS | SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; +#endif + + smbc_set_context(smb_context); + + m_initialized_smbc = true; + } + + return true; +} + diff --git a/tdeioslave/smb/tdeio_smb_browse.cpp b/tdeioslave/smb/tdeio_smb_browse.cpp new file mode 100644 index 000000000..e06bb81d1 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_browse.cpp @@ -0,0 +1,476 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_browse.cpp +// +// Abstract: member function implementations for SMBSlave that deal with +// SMB browsing +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include + +#include + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + +using namespace TDEIO; + +int SMBSlave::cache_stat(const SMBUrl &url, struct stat* st ) +{ + int result = smbc_stat( url.toSmbcUrl(), st); + kdDebug(KIO_SMB) << "smbc_stat " << url << " " << errno << " " << result << endl; + kdDebug(KIO_SMB) << "size " << (TDEIO::filesize_t)st->st_size << endl; + return result; +} + +//--------------------------------------------------------------------------- +bool SMBSlave::browse_stat_path(const SMBUrl& _url, UDSEntry& udsentry, bool ignore_errors) + // Returns: true on success, false on failure +{ + UDSAtom udsatom; + + SMBUrl url = _url; + + if(cache_stat(url, &st) == 0) + { + if(!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) + { + kdDebug(KIO_SMB)<<"SMBSlave::browse_stat_path mode: "<pw_name; + else + udsatom.m_str = TQString::number( uid ); + udsentry.append(udsatom); + + udsatom.m_uds = TDEIO::UDS_GROUP; + gid_t gid = st.st_gid; + struct group *grp = getgrgid( gid ); + if ( grp ) + udsatom.m_str = grp->gr_name; + else + udsatom.m_str = TQString::number( gid ); + udsentry.append(udsatom); + + udsatom.m_uds = TDEIO::UDS_ACCESS; + udsatom.m_long = st.st_mode & 07777; + udsentry.append(udsatom); + + udsatom.m_uds = UDS_MODIFICATION_TIME; + udsatom.m_long = st.st_mtime; + udsentry.append(udsatom); + + udsatom.m_uds = UDS_ACCESS_TIME; + udsatom.m_long = st.st_atime; + udsentry.append(udsatom); + + udsatom.m_uds = UDS_CREATION_TIME; + udsatom.m_long = st.st_ctime; + udsentry.append(udsatom); + + } + else + { + if (!ignore_errors) { + if (errno == EPERM || errno == EACCES) + if (checkPassword(url)) { + redirection( url ); + return false; + } + + reportError(url); + } else if (errno == ENOENT || errno == ENOTDIR) { + warning(i18n("File does not exist: %1").arg(url.url())); + } + kdDebug(KIO_SMB) << "SMBSlave::browse_stat_path ERROR!!"<< endl; + return false; + } + + return true; +} + +//=========================================================================== +void SMBSlave::stat( const KURL& kurl ) +{ + kdDebug(KIO_SMB) << "SMBSlave::stat on "<< kurl << endl; + // make a valid URL + KURL url = checkURL(kurl); + + // if URL is not valid we have to redirect to correct URL + if (url != kurl) + { + kdDebug() << "redirection " << url << endl; + redirection(url); + finished(); + return; + } + + m_current_url = url; + + UDSAtom udsatom; + UDSEntry udsentry; + // Set name + udsatom.m_uds = TDEIO::UDS_NAME; + udsatom.m_str = kurl.fileName(); + udsentry.append( udsatom ); + + switch(m_current_url.getType()) + { + case SMBURLTYPE_UNKNOWN: + error(ERR_MALFORMED_URL,m_current_url.prettyURL()); + finished(); + return; + + case SMBURLTYPE_ENTIRE_NETWORK: + case SMBURLTYPE_WORKGROUP_OR_SERVER: + udsatom.m_uds = TDEIO::UDS_FILE_TYPE; + udsatom.m_long = S_IFDIR; + udsentry.append(udsatom); + break; + + case SMBURLTYPE_SHARE_OR_PATH: + if (browse_stat_path(m_current_url, udsentry, false)) + break; + else { + kdDebug(KIO_SMB) << "SMBSlave::stat ERROR!!"<< endl; + finished(); + return; + } + default: + kdDebug(KIO_SMB) << "SMBSlave::stat UNKNOWN " << url << endl; + finished(); + return; + } + + statEntry(udsentry); + finished(); +} + +//=========================================================================== +// TODO: complete checking +KURL SMBSlave::checkURL(const KURL& kurl) const +{ + kdDebug(KIO_SMB) << "checkURL " << kurl << endl; + TQString surl = kurl.url(); + if (surl.startsWith("smb:/")) { + if (surl.length() == 5) // just the above + return kurl; // unchanged + + if (surl.at(5) != '/') { + surl = "smb://" + surl.mid(5); + kdDebug(KIO_SMB) << "checkURL return1 " << surl << " " << KURL(surl) << endl; + return KURL(surl); + } + } + + // smb:/ normaly have no userinfo + // we must redirect ourself to remove the username and password + if (surl.contains('@') && !surl.contains("smb://")) { + KURL url(kurl); + url.setPath("/"+kurl.url().right( kurl.url().length()-kurl.url().find('@') -1)); + TQString userinfo = kurl.url().mid(5, kurl.url().find('@')-5); + if(userinfo.contains(':')) { + url.setUser(userinfo.left(userinfo.find(':'))); + url.setPass(userinfo.right(userinfo.length()-userinfo.find(':')-1)); + } else { + url.setUser(userinfo); + } + kdDebug(KIO_SMB) << "checkURL return2 " << url << endl; + return url; + } + + // no emtpy path + KURL url(kurl); + + if (url.path().isEmpty()) + url.setPath("/"); + + kdDebug(KIO_SMB) << "checkURL return3 " << url << endl; + return url; +} + +void SMBSlave::reportError(const SMBUrl &url) +{ + kdDebug(KIO_SMB) << "reportError " << url << " " << perror << endl; + switch(errno) + { + case ENOENT: + if (url.getType() == SMBURLTYPE_ENTIRE_NETWORK) + error( ERR_SLAVE_DEFINED, i18n("Unable to find any workgroups in your local network. This might be caused by an enabled firewall.")); + else + error( ERR_DOES_NOT_EXIST, url.prettyURL()); + break; +#ifdef ENOMEDIUM + case ENOMEDIUM: + error( ERR_SLAVE_DEFINED, + i18n( "No media in device for %1" ).arg( url.prettyURL() ) ); + break; +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN: +#endif + case ECONNREFUSED: + error( ERR_SLAVE_DEFINED, + i18n( "Could not connect to host for %1" ).arg( url.prettyURL() ) ); + break; + case ENOTDIR: + error( ERR_CANNOT_ENTER_DIRECTORY, url.prettyURL()); + break; + case EFAULT: + case EINVAL: + error( ERR_DOES_NOT_EXIST, url.prettyURL()); + break; + case EPERM: + case EACCES: + error( ERR_ACCESS_DENIED, url.prettyURL() ); + break; + case EIO: + case ENETUNREACH: + if ( url.getType() == SMBURLTYPE_ENTIRE_NETWORK || url.getType() == SMBURLTYPE_WORKGROUP_OR_SERVER ) + error( ERR_SLAVE_DEFINED, i18n( "Error while connecting to server responsible for %1" ).arg( url.prettyURL() ) ); + else + error( ERR_CONNECTION_BROKEN, url.prettyURL()); + break; + case ENOMEM: + error( ERR_OUT_OF_MEMORY, url.prettyURL() ); + break; + case ENODEV: + error( ERR_SLAVE_DEFINED, i18n("Share could not be found on given server")); + break; + case EBADF: + error( ERR_INTERNAL, i18n("BAD File descriptor")); + break; + case ETIMEDOUT: + error( ERR_SERVER_TIMEOUT, url.host() ); + break; +#ifdef ENOTUNIQ + case ENOTUNIQ: + error( ERR_SLAVE_DEFINED, i18n( "The given name could not be resolved to a unique server. " + "Make sure your network is setup without any name conflicts " + "between names used by Windows and by UNIX name resolution." ) ); + break; +#endif + case 0: // success + error( ERR_INTERNAL, i18n("libsmbclient reported an error, but did not specify " + "what the problem is. This might indicate a severe problem " + "with your network - but also might indicate a problem with " + "libsmbclient.\n" + "If you want to help us, please provide a tcpdump of the " + "network interface while you try to browse (be aware that " + "it might contain private data, so do not post it if you are " + "unsure about that - you can send it privately to the developers " + "if they ask for it)") ); + break; + default: + error( ERR_INTERNAL, i18n("Unknown error condition in stat: %1").arg(TQString::fromLocal8Bit( strerror(errno))) ); + } +} + +//=========================================================================== +void SMBSlave::listDir( const KURL& kurl ) +{ + kdDebug(KIO_SMB) << "SMBSlave::listDir on " << kurl << endl; + + // check (correct) URL + KURL url = checkURL(kurl); + // if URL is not valid we have to redirect to correct URL + if (url != kurl) + { + redirection(url); + finished(); + return; + } + + m_current_url = kurl; + + int dirfd; + struct smbc_dirent *dirp = NULL; + UDSEntry udsentry; + UDSAtom atom; + + dirfd = smbc_opendir( m_current_url.toSmbcUrl() ); + kdDebug(KIO_SMB) << "SMBSlave::listDir open " << m_current_url.toSmbcUrl() << " " << m_current_url.getType() << " " << dirfd << endl; + if(dirfd >= 0) + { + do { + kdDebug(KIO_SMB) << "smbc_readdir " << endl; + dirp = smbc_readdir(dirfd); + if(dirp == 0) + break; + + // Set name + atom.m_uds = TDEIO::UDS_NAME; + TQString dirpName = TQString::fromUtf8( dirp->name ); + // We cannot trust dirp->commentlen has it might be with or without the NUL character + // See KDE bug #111430 and Samba bug #3030 + TQString comment = TQString::fromUtf8( dirp->comment ); + if ( dirp->smbc_type == SMBC_SERVER || dirp->smbc_type == SMBC_WORKGROUP ) { + atom.m_str = dirpName.lower(); + atom.m_str.at( 0 ) = dirpName.at( 0 ).upper(); + if ( !comment.isEmpty() && dirp->smbc_type == SMBC_SERVER ) + atom.m_str += " (" + comment + ")"; + } else + atom.m_str = dirpName; + + kdDebug(KIO_SMB) << "dirp->name " << dirp->name << " " << dirpName << " '" << comment << "'" << " " << dirp->smbc_type << endl; + + udsentry.append( atom ); + if (atom.m_str.upper()=="IPC$" || atom.m_str=="." || atom.m_str == ".." || + atom.m_str.upper() == "ADMIN$" || atom.m_str.lower() == "printer$" || atom.m_str.lower() == "print$" ) + { +// fprintf(stderr,"----------- hide: -%s-\n",dirp->name); + // do nothing and hide the hidden shares + } + else if(dirp->smbc_type == SMBC_FILE) + { + // Set stat information + m_current_url.addPath(dirpName); + browse_stat_path(m_current_url, udsentry, true); + m_current_url.cd(".."); + + // Call base class to list entry + listEntry(udsentry, false); + } + else if(dirp->smbc_type == SMBC_DIR) + { + m_current_url.addPath(dirpName); + browse_stat_path(m_current_url, udsentry, true); + m_current_url.cd(".."); + + // Call base class to list entry + listEntry(udsentry, false); + } + else if(dirp->smbc_type == SMBC_SERVER || + dirp->smbc_type == SMBC_FILE_SHARE) + { + // Set type + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + udsentry.append( atom ); + + // Set permissions + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = (S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH); + udsentry.append(atom); + + if (dirp->smbc_type == SMBC_SERVER) { + atom.m_uds = TDEIO::UDS_URL; + // TQString workgroup = m_current_url.host().upper(); + KURL u("smb:/"); + u.setHost(dirpName); + atom.m_str = u.url(); + + // when libsmbclient knows + // atom.m_str = TQString("smb://%1?WORKGROUP=%2").arg(dirpName).arg(workgroup.upper()); + kdDebug(KIO_SMB) << "list item " << atom.m_str << endl; + udsentry.append(atom); + + atom.m_uds = TDEIO::UDS_MIME_TYPE; + atom.m_str = TQString::fromLatin1("application/x-smb-server"); + udsentry.append(atom); + } + + // Call base class to list entry + listEntry(udsentry, false); + } + else if(dirp->smbc_type == SMBC_WORKGROUP) + { + // Set type + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + udsentry.append( atom ); + + // Set permissions + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = (S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH); + udsentry.append(atom); + + atom.m_uds = TDEIO::UDS_MIME_TYPE; + atom.m_str = TQString::fromLatin1("application/x-smb-workgroup"); + udsentry.append(atom); + + atom.m_uds = TDEIO::UDS_URL; + // TQString workgroup = m_current_url.host().upper(); + KURL u("smb:/"); + u.setHost(dirpName); + atom.m_str = u.url(); + udsentry.append(atom); + + // Call base class to list entry + listEntry(udsentry, false); + } + else + { + kdDebug(KIO_SMB) << "SMBSlave::listDir SMBC_UNKNOWN :" << dirpName << endl; + // TODO: we don't handle SMBC_IPC_SHARE, SMBC_PRINTER_SHARE + // SMBC_LINK, SMBC_COMMS_SHARE + //SlaveBase::error(ERR_INTERNAL, TEXT_UNSUPPORTED_FILE_TYPE); + // continue; + } + udsentry.clear(); + } while (dirp); // checked already in the head + + // clean up + smbc_closedir(dirfd); + } + else + { + if (errno == EPERM || errno == EACCES) + if (checkPassword(m_current_url)) { + redirection( m_current_url ); + finished(); + return; + } + + reportError(m_current_url); + finished(); + return; + } + + listEntry(udsentry, true); + finished(); +} + diff --git a/tdeioslave/smb/tdeio_smb_config.cpp b/tdeioslave/smb/tdeio_smb_config.cpp new file mode 100644 index 000000000..f2f1ce562 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_config.cpp @@ -0,0 +1,66 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_config.cpp +// +// Abstract: member function implementations for SMBSlave that deal with +// KDE/SMB slave configuration +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" +#include + +#include +//=========================================================================== +void SMBSlave::reparseConfiguration() +{ + TDEConfig *cfg = new TDEConfig("tdeioslaverc", true); + cfg->setGroup("Browser Settings/SMBro"); + m_default_user=cfg->readEntry("User"); +// m_default_workgroup=cfg->readEntry("Workgroup"); +// m_showHiddenShares=cfg->readBoolEntry("ShowHiddenShares",false); + + TQString m_encoding = TQTextCodec::codecForLocale()->name(); + m_default_encoding = cfg->readEntry( "Encoding", m_encoding.lower() ); + + // unscramble, taken from Nicola Brodu's smb ioslave + //not really secure, but better than storing the plain password + TQString scrambled = cfg->readEntry( "Password" ); + m_default_password = ""; + for (uint i=0; i +// +////--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + + +//=========================================================================== +// TODO: add when libsmbclient supports it +void SMBSlave::copy( const KURL& ksrc, + const KURL& kdst, + int permissions, + bool overwrite) +{ + + SMBUrl src; + SMBUrl dst; + mode_t initialmode; + int n; + int dstflags; + int srcfd = -1; + int dstfd = -1; + TDEIO::filesize_t processed_size = 0; + unsigned char buf[MAX_XFER_BUF_SIZE]; + + kdDebug(KIO_SMB) << "SMBSlave::copy with src = " << ksrc << "and dest = " << kdst << endl; + + // setup urls + src = ksrc; + dst = kdst; + + // Obtain information about source + if(cache_stat(src, &st ) == -1) + { + if ( errno == EACCES ) + { + error( TDEIO::ERR_ACCESS_DENIED, src.prettyURL()); + } + else + { + error( TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL()); + } + return; + } + if ( S_ISDIR( st.st_mode ) ) + { + error( TDEIO::ERR_IS_DIRECTORY, src.prettyURL() ); + return; + } + totalSize(st.st_size); + + // Check to se if the destination exists + if(cache_stat(dst, &st) != -1) + { + if(S_ISDIR(st.st_mode)) + { + error( TDEIO::ERR_DIR_ALREADY_EXIST, dst.prettyURL()); + return; + } + if(!overwrite) + { + error( TDEIO::ERR_FILE_ALREADY_EXIST, dst.prettyURL()); + return; + } + } + + // Open the source file + srcfd = smbc_open(src.toSmbcUrl(), O_RDONLY, 0); + if(srcfd < 0) + { + if(errno == EACCES) + { + error( TDEIO::ERR_ACCESS_DENIED, src.prettyURL() ); + } + else + { + error( TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL() ); + } + return; + } + + // Determine initial creation mode + if(permissions != -1) + { + initialmode = permissions | S_IWUSR; + } + else + { + initialmode = 0 | S_IWUSR;//0666; + } + + + // Open the destination file + dstflags = O_CREAT | O_TRUNC | O_WRONLY; + if(!overwrite) + { + dstflags |= O_EXCL; + } + dstfd = smbc_open(dst.toSmbcUrl(), dstflags, initialmode); + if(dstfd < 0) + { + if(errno == EACCES) + { + error(TDEIO::ERR_WRITE_ACCESS_DENIED, dst.prettyURL()); + } + else + { + error(TDEIO::ERR_CANNOT_OPEN_FOR_READING, dst.prettyURL()); + } + if(srcfd >= 0 ) + { + smbc_close(srcfd); + } + return; + } + + + // Perform copy + while(1) + { + n = smbc_read(srcfd, buf, MAX_XFER_BUF_SIZE ); + if(n > 0) + { + n = smbc_write(dstfd, buf, n); + if(n == -1) + { + kdDebug(KIO_SMB) << "SMBSlave::copy copy now TDEIO::ERR_COULD_NOT_WRITE" << endl; + error( TDEIO::ERR_COULD_NOT_WRITE, dst.prettyURL()); + break; + } + + processed_size += n; + processedSize(processed_size); + } + else if(n == 0) + { + break; // finished + } + else + { + error( TDEIO::ERR_COULD_NOT_READ, src.prettyURL()); + break; + } + } + + + // FINISHED: + + if(srcfd >= 0 ) + { + smbc_close(srcfd); + } + + if(dstfd >= 0) + { + if(smbc_close(dstfd) == 0) + { + + // TODO: set final permissions + } + else + { + error( TDEIO::ERR_COULD_NOT_WRITE, dst.prettyURL()); + return; + } + } + + finished(); +} + +//=========================================================================== +void SMBSlave::del( const KURL &kurl, bool isfile) +{ + kdDebug(KIO_SMB) << "SMBSlave::del on " << kurl << endl; + m_current_url = kurl; + + if(isfile) + { + // Delete file + kdDebug(KIO_SMB) << "SMBSlave:: unlink " << kurl << endl; + if(smbc_unlink(m_current_url.toSmbcUrl()) == -1) + { + switch(errno) + { + case EISDIR: + error( TDEIO::ERR_IS_DIRECTORY, m_current_url.prettyURL()); + break; + default: + reportError(kurl); + } + } + } + else + { + kdDebug(KIO_SMB) << "SMBSlave:: rmdir " << kurl << endl; + // Delete directory + if(smbc_rmdir(m_current_url.toSmbcUrl()) == -1) + { + reportError(kurl); + } + } + + finished(); +} + +//=========================================================================== +void SMBSlave::mkdir( const KURL &kurl, int permissions ) +{ + kdDebug(KIO_SMB) << "SMBSlave::mkdir on " << kurl << endl; + m_current_url = kurl; + + if(smbc_mkdir(m_current_url.toSmbcUrl(), 0777) != 0) + { + if (errno == EEXIST) { + if(cache_stat(m_current_url, &st ) == 0) + { + if(S_ISDIR(st.st_mode )) + { + error( TDEIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL()); + } + } + else + { + error( TDEIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL()); + } + } else + reportError(kurl); + kdDebug(KIO_SMB) << "SMBSlave::mkdir exit with error " << kurl << endl; + } + else + { + if(permissions != -1) + { + // TODO enable the following when complete + //smbc_chmod( url.toSmbcUrl(), permissions ); + } + } + + finished(); +} + + +//=========================================================================== +void SMBSlave::rename( const KURL& ksrc, const KURL& kdest, bool overwrite ) +{ + + SMBUrl src; + SMBUrl dst; + + kdDebug(KIO_SMB) << "SMBSlave::rename, old name = " << ksrc << ", new name = " << kdest << endl; + + src = ksrc; + dst = kdest; + + // Check to se if the destination exists + + kdDebug(KIO_SMB) << "SMBSlave::rename stat dst" << endl; + if(cache_stat(dst, &st) != -1) + { + if(S_ISDIR(st.st_mode)) + { + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_DIR_ALREADY_EXIST" << endl; + error( TDEIO::ERR_DIR_ALREADY_EXIST, dst.prettyURL()); + finished(); + return; + } + if(!overwrite) + { + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_FILE_ALREADY_EXIST" << endl; + error( TDEIO::ERR_FILE_ALREADY_EXIST, dst.prettyURL()); + finished(); + return; + } + } + kdDebug(KIO_SMB ) << "smbc_rename " << src.toSmbcUrl() << " " << dst.toSmbcUrl() << endl; + if(smbc_rename(src.toSmbcUrl(), dst.toSmbcUrl())!=0) + { + kdDebug(KIO_SMB ) << "failed " << perror << endl; + switch(errno) + { + case ENOENT: + if(cache_stat(src, &st) == -1) + { + if(errno == EACCES) + { + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_ACCESS_DENIED" << endl; + error(TDEIO::ERR_ACCESS_DENIED, src.prettyURL()); + } + else + { + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_DOES_NOT_EXIST" << endl; + error(TDEIO::ERR_DOES_NOT_EXIST, src.prettyURL()); + } + } + break; + + case EACCES: + case EPERM: + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_ACCESS_DENIED" << endl; + error( TDEIO::ERR_ACCESS_DENIED, dst.prettyURL() ); + break; + + default: + kdDebug(KIO_SMB) << "SMBSlave::rename TDEIO::ERR_CANNOT_RENAME" << endl; + error( TDEIO::ERR_CANNOT_RENAME, src.prettyURL() ); + + } + + kdDebug(KIO_SMB) << "SMBSlave::rename exit with error" << endl; + return; + } + + kdDebug(KIO_SMB ) << "everything fine\n"; + finished(); +} + + diff --git a/tdeioslave/smb/tdeio_smb_file.cpp b/tdeioslave/smb/tdeio_smb_file.cpp new file mode 100644 index 000000000..a6c010526 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_file.cpp @@ -0,0 +1,279 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_file.cpp +// +// Abstract: member function implementations for SMBSlave that deal with +// SMB file access +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + +#include + +//=========================================================================== +void SMBSlave::get( const KURL& kurl ) +{ + char buf[MAX_XFER_BUF_SIZE]; + int filefd = 0; + ssize_t bytesread = 0; + // time_t curtime = 0; + time_t lasttime = 0; + time_t starttime = 0; + TDEIO::filesize_t totalbytesread = 0; + TQByteArray filedata; + SMBUrl url; + + kdDebug(KIO_SMB) << "SMBSlave::get on " << kurl << endl; + + // check (correct) URL + KURL kvurl = checkURL(kurl); + // if URL is not valid we have to redirect to correct URL + if (kvurl != kurl) { + redirection(kvurl); + finished(); + return; + } + + if(!auth_initialize_smbc()) + return; + + + // Stat + url = kurl; + if(cache_stat(url,&st) == -1 ) + { + if ( errno == EACCES ) + error( TDEIO::ERR_ACCESS_DENIED, url.prettyURL()); + else + error( TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + return; + } + if ( S_ISDIR( st.st_mode ) ) { + error( TDEIO::ERR_IS_DIRECTORY, url.prettyURL()); + return; + } + + // Set the total size + totalSize( st.st_size ); + + // Open and read the file + filefd = smbc_open(url.toSmbcUrl(),O_RDONLY,0); + if(filefd >= 0) + { + if(buf) + { + bool isFirstPacket = true; + lasttime = starttime = time(NULL); + while(1) + { + bytesread = smbc_read(filefd, buf, MAX_XFER_BUF_SIZE); + if(bytesread == 0) + { + // All done reading + break; + } + else if(bytesread < 0) + { + error( TDEIO::ERR_COULD_NOT_READ, url.prettyURL()); + return; + } + + filedata.setRawData(buf,bytesread); + if (isFirstPacket) + { + // We need a KMimeType::findByNameAndContent(filename,data) + // For now we do: find by extension, and if not found (or extension not reliable) + // then find by content. + bool accurate = false; + KMimeType::Ptr mime = KMimeType::findByURL( kurl, st.st_mode, false, true, &accurate ); + if ( !mime || mime->name() == KMimeType::defaultMimeType() + || !accurate ) + { + KMimeType::Ptr p_mimeType = KMimeType::findByContent(filedata); + if ( p_mimeType && p_mimeType->name() != KMimeType::defaultMimeType() ) + mime = p_mimeType; + } + mimeType(mime->name()); + isFirstPacket = false; + } + data( filedata ); + filedata.resetRawData(buf,bytesread); + + // increment total bytes read + totalbytesread += bytesread; + + processedSize(totalbytesread); + } + } + + smbc_close(filefd); + data( TQByteArray() ); + processedSize(static_cast(st.st_size)); + + } + else + { + error( TDEIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL()); + return; + } + + finished(); +} + + +//=========================================================================== +void SMBSlave::put( const KURL& kurl, + int permissions, + bool overwrite, + bool resume ) +{ + + void *buf; + size_t bufsize; + + m_current_url = kurl; + + int filefd; + bool exists; + mode_t mode; + TQByteArray filedata; + + kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl << endl; + + + exists = (cache_stat(m_current_url, &st) != -1 ); + if ( exists && !overwrite && !resume) + { + if (S_ISDIR(st.st_mode)) + { + kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already isdir !!"<< endl; + error( TDEIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL()); + } + else + { + kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already exist !!"<< endl; + error( TDEIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL()); + } + return; + } + + if (exists && !resume && overwrite) + { + kdDebug(KIO_SMB) << "SMBSlave::put exists try to remove " << m_current_url.toSmbcUrl()<< endl; + // remove(m_current_url.url().local8Bit()); + } + + + if (resume) + { + // append if resuming + kdDebug(KIO_SMB) << "SMBSlave::put resume " << m_current_url.toSmbcUrl()<< endl; + filefd = smbc_open(m_current_url.toSmbcUrl(), O_RDWR, 0 ); + smbc_lseek(filefd, 0, SEEK_END); + } + else + { + if (permissions != -1) + { + mode = permissions | S_IWUSR | S_IRUSR; + } + else + { + mode = 600;//0666; + } + + kdDebug(KIO_SMB) << "SMBSlave::put NO resume " << m_current_url.toSmbcUrl()<< endl; + filefd = smbc_open(m_current_url.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode); + } + + if ( filefd < 0 ) + { + if ( errno == EACCES ) + { + kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" access denied !!"<< endl; + error( TDEIO::ERR_WRITE_ACCESS_DENIED, m_current_url.prettyURL()); + } + else + { + kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" can not open for writing !!"<< endl; + error( TDEIO::ERR_CANNOT_OPEN_FOR_WRITING, m_current_url.prettyURL()); + } + finished(); + return; + } + + // Loop until we got 0 (end of data) + while(1) + { + kdDebug(KIO_SMB) << "SMBSlave::put request data "<< endl; + dataReq(); // Request for data + kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; + + if (readData(filedata) <= 0) + { + kdDebug(KIO_SMB) << "readData <= 0" << endl; + break; + } + kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; + buf = filedata.data(); + bufsize = filedata.size(); + int size = smbc_write(filefd, buf, bufsize); + if ( size < 0) + { + kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" could not write !!"<< endl; + error( TDEIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); + finished(); + return; + } + kdDebug(KIO_SMB ) << "wrote " << size << endl; + } + kdDebug(KIO_SMB) << "SMBSlave::put close " << m_current_url.toSmbcUrl()<< endl; + + if(smbc_close(filefd)) + { + kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" could not write !!"<< endl; + error( TDEIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); + finished(); + return; + } + + // set final permissions, if the file was just created + if ( permissions != -1 && !exists ) + { + // TODO: did the smbc_chmod fail? + // TODO: put in call to chmod when it is working! + // smbc_chmod(url.toSmbcUrl(),permissions); + } + + // We have done our job => finish + finished(); +} + + + + diff --git a/tdeioslave/smb/tdeio_smb_internal.cpp b/tdeioslave/smb/tdeio_smb_internal.cpp new file mode 100644 index 000000000..de3f98127 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_internal.cpp @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_internal.cpp +// +// Abstract: Utility class implementation used by SMBSlave +// +// Author(s): Matthew Peterson +// +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#include "tdeio_smb.h" +#include "tdeio_smb_internal.h" + +#include + +#include +#include + + +//=========================================================================== +// SMBUrl Function Implementation +//=========================================================================== + +//----------------------------------------------------------------------- +SMBUrl::SMBUrl() +{ + m_type = SMBURLTYPE_UNKNOWN; +} + +//----------------------------------------------------------------------- +SMBUrl::SMBUrl(const KURL& kurl) + : KURL(kurl) + //----------------------------------------------------------------------- +{ + updateCache(); +} + + +//----------------------------------------------------------------------- +void SMBUrl::addPath(const TQString &filedir) +{ + KURL::addPath(filedir); + updateCache(); +} + +//----------------------------------------------------------------------- +bool SMBUrl::cd(const TQString &filedir) +{ + if (!KURL::cd(filedir)) + return false; + updateCache(); + return true; +} + +//----------------------------------------------------------------------- +void SMBUrl::updateCache() + //----------------------------------------------------------------------- +{ + cleanPath(); + + // SMB URLs are UTF-8 encoded + kdDebug(KIO_SMB) << "updateCache " << KURL::path() << endl; + if (KURL::url() == "smb:/") + m_surl = "smb://"; + else { + TQString surl = "smb://"; + if (KURL::hasUser()) { + surl += KURL::encode_string(KURL::user(), 106); + if (KURL::hasPass()) { + surl += ":" + KURL::encode_string(KURL::pass(), 106); + } + surl += "@"; + } + surl += KURL::encode_string(KURL::host().upper(), 106); + surl += KURL::encode_string(KURL::path(), 106); + m_surl = surl.utf8(); + } + m_type = SMBURLTYPE_UNKNOWN; + // update m_type + (void)getType(); +} + +//----------------------------------------------------------------------- +SMBUrlType SMBUrl::getType() const + // Returns the type of this SMBUrl: + // SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. + // SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network + // SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" + // SMBURLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" + //----------------------------------------------------------------------- +{ + if(m_type != SMBURLTYPE_UNKNOWN) + return m_type; + + if (protocol() != "smb") + { + m_type = SMBURLTYPE_UNKNOWN; + return m_type; + } + + if (path(1) == "/") + { + if (host().isEmpty()) + m_type = SMBURLTYPE_ENTIRE_NETWORK; + else + m_type = SMBURLTYPE_WORKGROUP_OR_SERVER; + return m_type; + } + + // Check for the path if we get this far + m_type = SMBURLTYPE_SHARE_OR_PATH; + + return m_type; +} + diff --git a/tdeioslave/smb/tdeio_smb_internal.h b/tdeioslave/smb/tdeio_smb_internal.h new file mode 100644 index 000000000..3eeae43a7 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_internal.h @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Project: SMB tdeioslave for KDE2 +// +// File: tdeio_smb_internal.h +// +// Abstract: Utility classes used by SMBSlave +// +// Author(s): Matthew Peterson +// Frank Schwanz +//--------------------------------------------------------------------------- +// +// Copyright (c) 2000 Caldera Systems, Inc. +// +// 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; either version 2.1 of the License, or +// (at your option) any later version. +// +// 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 Lesser 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, please obtain +// a copy from http://www.gnu.org/copyleft/gpl.html +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef KIO_SMB_INTERNAL_H_INCLUDED +#define KIO_SMB_INTERNAL_H_INCLUDED + +#include + +/** + * Types of a SMBURL : + * SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. + * SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network + * SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" + * URLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" + */ +enum SMBUrlType { + SMBURLTYPE_UNKNOWN = 0, SMBURLTYPE_ENTIRE_NETWORK = 1, + SMBURLTYPE_WORKGROUP_OR_SERVER = 2, SMBURLTYPE_SHARE_OR_PATH = 3 +}; + + +//=========================================================================== +/** + * Class to handle URL's + * it can convert KURL to smbUrl + * and Handle UserInfo + * it also check the correctness of the URL + */ +class SMBUrl : public KURL +{ + + +public: + SMBUrl(); + SMBUrl(const KURL & kurl); + + /** + * Appends the specified file and dir to this SMBUrl + * "smb://server/share" --> "smb://server/share/filedir" + */ + void addPath(const TQString &filedir); + + bool cd(const TQString &dir); + + /** + * Returns the type of this SMBUrl: + * SMBURLTYPE_UNKNOWN - Type could not be determined. Bad SMB Url. + * SMBURLTYPE_ENTIRE_NETWORK - "smb:/" is entire network + * SMBURLTYPE_WORKGROUP_OR_SERVER - "smb:/mygroup" or "smb:/myserver" + * URLTYPE_SHARE_OR_PATH - "smb:/mygroupe/mymachine/myshare/mydir" + */ + SMBUrlType getType() const; + + void setPass( const TQString& _txt ) { KURL::setPass(_txt); updateCache(); } + void setUser( const TQString& _txt ) { KURL::setUser(_txt); updateCache(); } + void setHost( const TQString& _txt ) { KURL::setHost(_txt); updateCache(); } + + /** + * Returns the workgroup if it given in url + */ +// TQString getWorkgroup() const; + + /** + * Returns path after workgroup + */ +// TQString getServerShareDir() const; + + /** + * Return a URL that is suitable for libsmbclient + */ + TQCString toSmbcUrl() const { return m_surl; } + +private: + /** + * Change from TQString to TQCString (MS Windows's character encoding) + */ + TQCString fromUnicode( const TQString &_str ) const; + + void updateCache(); + TQCString m_surl; + + /** + * Type of URL + * @see _SMBUrlType + */ + mutable SMBUrlType m_type; +}; + + +#endif + diff --git a/tdeioslave/smb/tdeio_smb_mount.cpp b/tdeioslave/smb/tdeio_smb_mount.cpp new file mode 100644 index 000000000..1cda7f5f4 --- /dev/null +++ b/tdeioslave/smb/tdeio_smb_mount.cpp @@ -0,0 +1,211 @@ +/* This file is part of the KDE project + + Copyright (C) 2000 Alexander Neundorf + + 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 "tdeio_smb.h" +#include +#include +#include +#include +#include + +void SMBSlave::readOutput(TDEProcess *, char *buffer, int buflen) +{ + mybuf += TQString::fromLocal8Bit(buffer, buflen); +} + +void SMBSlave::readStdErr(TDEProcess *, char *buffer, int buflen) +{ + mystderr += TQString::fromLocal8Bit(buffer, buflen); +} + +void SMBSlave::special( const TQByteArray & data) +{ + kdDebug(KIO_SMB)<<"Smb::special()"<> tmp; + //mounting and umounting are both blocking, "guarded" by a SIGALARM in the future + switch (tmp) + { + case 1: + case 3: + { + TQString remotePath, mountPoint, user; + stream >> remotePath >> mountPoint; + + TQStringList sl=TQStringList::split("/",remotePath); + TQString share,host; + if (sl.count()>=2) + { + host=(*sl.at(0)).mid(2); + share=(*sl.at(1)); + kdDebug(KIO_SMB)<<"special() host -"<< host <<"- share -" << share <<"-"<> mountPoint; + + TDEProcess proc; + proc.setUseShell(true); + proc << "smbumount"; + proc << TDEProcess::quote(mountPoint); + + mybuf.truncate(0); + mystderr.truncate(0); + + connect(&proc, TQT_SIGNAL( receivedStdout(TDEProcess *, char *, int )), + TQT_SLOT(readOutput(TDEProcess *, char *, int))); + + connect(&proc, TQT_SIGNAL( receivedStderr(TDEProcess *, char *, int )), + TQT_SLOT(readStdErr(TDEProcess *, char *, int))); + + if ( !proc.start( TDEProcess::Block, TDEProcess::AllOutput ) ) + { + error(TDEIO::ERR_CANNOT_LAUNCH_PROCESS, + "smbumount"+i18n("\nMake sure that the samba package is installed properly on your system.")); + return; + } + + kdDebug(KIO_SMB) << "smbumount exit " << proc.exitStatus() << endl + << "stdout:" << mybuf << endl << "stderr:" << mystderr << endl; + + if (proc.exitStatus() != 0) + { + error(TDEIO::ERR_COULD_NOT_UNMOUNT, + i18n("Unmounting of mountpoint \"%1\" failed.\n%2") + .arg(mountPoint).arg(mybuf + "\n" + mystderr)); + return; + } + + if ( tmp == 4 ) + { + bool ok; + + TQDir dir(mountPoint); + dir.cdUp(); + ok = dir.rmdir(mountPoint); + if ( ok ) + { + TQString p=dir.path(); + dir.cdUp(); + ok = dir.rmdir(p); + } + + if ( !ok ) + { + error(TDEIO::ERR_COULD_NOT_RMDIR, mountPoint); + return; + } + } + + finished(); + } + break; + default: + break; + } + finished(); +} + +#include "tdeio_smb.moc" diff --git a/tdeioslave/smtp/CMakeLists.txt b/tdeioslave/smtp/CMakeLists.txt index 57095a364..f9171e665 100644 --- a/tdeioslave/smtp/CMakeLists.txt +++ b/tdeioslave/smtp/CMakeLists.txt @@ -26,9 +26,9 @@ link_directories( install( FILES smtp.protocol smtps.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_smtp (module) ######################### +##### tdeio_smtp (module) ######################### -set( target kio_smtp ) +set( target tdeio_smtp ) tde_add_kpart( ${target} AUTOMOC SOURCES smtp.cc request.cc response.cc capabilities.cc command.cc transactionstate.cc diff --git a/tdeioslave/smtp/Makefile.am b/tdeioslave/smtp/Makefile.am index 7808a24db..e6db9885c 100644 --- a/tdeioslave/smtp/Makefile.am +++ b/tdeioslave/smtp/Makefile.am @@ -1,11 +1,11 @@ INCLUDES= -I$(srcdir)/../.. -I$(srcdir)/.. $(SSL_INCLUDES) $(all_includes) -kde_module_LTLIBRARIES = kio_smtp.la +kde_module_LTLIBRARIES = tdeio_smtp.la -kio_smtp_la_SOURCES = smtp.cc request.cc response.cc capabilities.cc command.cc transactionstate.cc -kio_smtp_la_LIBADD = $(LIB_KIO) $(SASL2_LIBS) -kio_smtp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_smtp_la_SOURCES = smtp.cc request.cc response.cc capabilities.cc command.cc transactionstate.cc +tdeio_smtp_la_LIBADD = $(LIB_KIO) $(SASL2_LIBS) +tdeio_smtp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) noinst_HEADERS = smtp.h request.h response.h capabilities.h command.h transactionstate.h @@ -25,7 +25,7 @@ test_responseparser_LDADD = $(LIB_TDECORE) test_responseparser_LDFLAGS = $(all_libraries) test_commands_SOURCES = test_commands.cc -test_commands_LDADD = $(kio_smtp_la_LIBADD) +test_commands_LDADD = $(tdeio_smtp_la_LIBADD) test_commands_LDFLAGS = $(all_libraries) interactivesmtpserver_SOURCES = interactivesmtpserver.cc diff --git a/tdeioslave/smtp/capabilities.cc b/tdeioslave/smtp/capabilities.cc index bf91071b3..f4f20fa7a 100644 --- a/tdeioslave/smtp/capabilities.cc +++ b/tdeioslave/smtp/capabilities.cc @@ -1,7 +1,7 @@ /* -*- c++ -*- capabilities.cc - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/capabilities.h b/tdeioslave/smtp/capabilities.h index 5004cbaac..1af13e365 100644 --- a/tdeioslave/smtp/capabilities.h +++ b/tdeioslave/smtp/capabilities.h @@ -1,7 +1,7 @@ /* -*- c++ -*- capabilities.h - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/command.cc b/tdeioslave/smtp/command.cc index 3817d5fd6..8543f6c03 100644 --- a/tdeioslave/smtp/command.cc +++ b/tdeioslave/smtp/command.cc @@ -1,7 +1,7 @@ /* -*- c++ -*- command.cc - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it @@ -239,7 +239,7 @@ static sasl_callback_t callbacks[] = { kdDebug(7112) << "Mechanism: " << mMechusing << " one step: " << mOneStep << endl; #else mSMTP->error(TDEIO::ERR_COULD_NOT_AUTHENTICATE, - i18n("Authentication support is not compiled into kio_smtp.")); + i18n("Authentication support is not compiled into tdeio_smtp.")); #endif } diff --git a/tdeioslave/smtp/command.h b/tdeioslave/smtp/command.h index 48d08df22..c634d1a86 100644 --- a/tdeioslave/smtp/command.h +++ b/tdeioslave/smtp/command.h @@ -1,7 +1,7 @@ /* -*- c++ -*- command.h - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/interactivesmtpserver.cc b/tdeioslave/smtp/interactivesmtpserver.cc index 7e84b8d3e..5f25ca1ca 100644 --- a/tdeioslave/smtp/interactivesmtpserver.cc +++ b/tdeioslave/smtp/interactivesmtpserver.cc @@ -3,7 +3,7 @@ Code based on the serverSocket example by Jesper Pedersen. - This file is part of the testsuite of kio_smtp, the KDE SMTP tdeioslave. + This file is part of the testsuite of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2004 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/interactivesmtpserver.h b/tdeioslave/smtp/interactivesmtpserver.h index 3e4b4b29d..b4731d44c 100644 --- a/tdeioslave/smtp/interactivesmtpserver.h +++ b/tdeioslave/smtp/interactivesmtpserver.h @@ -6,7 +6,7 @@ Code based on the serverSocket example by Jesper Pedersen. - This file is part of the testsuite of kio_smtp, the KDE SMTP tdeioslave. + This file is part of the testsuite of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2004 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/request.cc b/tdeioslave/smtp/request.cc index 8019a04f7..4e3cde0e1 100644 --- a/tdeioslave/smtp/request.cc +++ b/tdeioslave/smtp/request.cc @@ -1,7 +1,7 @@ /* -*- c++ -*- request.cc - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/request.h b/tdeioslave/smtp/request.h index 21e2067fb..37d74d2de 100644 --- a/tdeioslave/smtp/request.h +++ b/tdeioslave/smtp/request.h @@ -1,7 +1,7 @@ /* -*- c++ -*- request.h - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/response.cc b/tdeioslave/smtp/response.cc index da5569cf7..6c29d31bf 100644 --- a/tdeioslave/smtp/response.cc +++ b/tdeioslave/smtp/response.cc @@ -1,7 +1,7 @@ /* -*- c++ -*- response.cc - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/response.h b/tdeioslave/smtp/response.h index 6c749b9e4..f2caf62e0 100644 --- a/tdeioslave/smtp/response.h +++ b/tdeioslave/smtp/response.h @@ -1,7 +1,7 @@ /* -*- c++ -*- response.h - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/smtp.cc b/tdeioslave/smtp/smtp.cc index aa3ebfe75..3dfb8a053 100644 --- a/tdeioslave/smtp/smtp.cc +++ b/tdeioslave/smtp/smtp.cc @@ -95,11 +95,11 @@ extern "C" { int kdemain(int argc, char **argv) { - TDEInstance instance("kio_smtp"); + TDEInstance instance("tdeio_smtp"); if (argc != 4) { fprintf(stderr, - "Usage: kio_smtp protocol domain-socket1 domain-socket2\n"); + "Usage: tdeio_smtp protocol domain-socket1 domain-socket2\n"); exit(-1); } @@ -199,7 +199,7 @@ void SMTPProtocol::put(const KURL & url, int /*permissions */ , KEMailSettings mset; KURL open_url = url; if ( !request.hasProfile() ) { - //kdDebug(7112) << "kio_smtp: Profile is null" << endl; + //kdDebug(7112) << "tdeio_smtp: Profile is null" << endl; bool hasProfile = mset.profiles().contains( open_url.host() ); if ( hasProfile ) { mset.setProfile(open_url.host()); diff --git a/tdeioslave/smtp/smtp.protocol b/tdeioslave/smtp/smtp.protocol index 9a90cc397..4e757c7bd 100644 --- a/tdeioslave/smtp/smtp.protocol +++ b/tdeioslave/smtp/smtp.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_smtp +exec=tdeio_smtp protocol=smtp Capabilities=SASL input=none diff --git a/tdeioslave/smtp/smtps.protocol b/tdeioslave/smtp/smtps.protocol index 2087845f2..177458777 100644 --- a/tdeioslave/smtp/smtps.protocol +++ b/tdeioslave/smtp/smtps.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_smtp +exec=tdeio_smtp protocol=smtps Capabilities=SASL input=none diff --git a/tdeioslave/smtp/transactionstate.cc b/tdeioslave/smtp/transactionstate.cc index 886fe35b5..71a3e682c 100644 --- a/tdeioslave/smtp/transactionstate.cc +++ b/tdeioslave/smtp/transactionstate.cc @@ -1,7 +1,7 @@ /* -*- c++ -*- transactionstate.cc - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/smtp/transactionstate.h b/tdeioslave/smtp/transactionstate.h index c62f52ae0..a5a78f49c 100644 --- a/tdeioslave/smtp/transactionstate.h +++ b/tdeioslave/smtp/transactionstate.h @@ -1,7 +1,7 @@ /* -*- c++ -*- transactionstate.h - This file is part of kio_smtp, the KDE SMTP tdeioslave. + This file is part of tdeio_smtp, the KDE SMTP tdeioslave. Copyright (c) 2003 Marc Mutz This program is free software; you can redistribute it and/or modify it diff --git a/tdeioslave/system/CMakeLists.txt b/tdeioslave/system/CMakeLists.txt index b9fea814d..113f9bfc3 100644 --- a/tdeioslave/system/CMakeLists.txt +++ b/tdeioslave/system/CMakeLists.txt @@ -29,22 +29,22 @@ link_directories( install( FILES system.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kiosystem (static) ######################## +##### tdeiosystem (static) ######################## -set( target kiosystem ) +set( target tdeiosystem ) tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES kio_system.cpp systemimpl.cpp + SOURCES tdeio_system.cpp systemimpl.cpp ) -##### kio_system (module) ####################### +##### tdeio_system (module) ####################### -set( target kio_system ) +set( target tdeio_system ) tde_add_kpart( ${target} AUTOMOC SOURCES dummy.cpp - EMBED kiosystem-static + EMBED tdeiosystem-static LINK tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/system/Makefile.am b/tdeioslave/system/Makefile.am index 5fc63eb5c..58d779a9b 100644 --- a/tdeioslave/system/Makefile.am +++ b/tdeioslave/system/Makefile.am @@ -3,11 +3,11 @@ SUBDIRS= . kdedmodule entries mimetypes INCLUDES = $(all_includes) METASOURCES = AUTO -kde_module_LTLIBRARIES = kio_system.la +kde_module_LTLIBRARIES = tdeio_system.la -kio_system_la_SOURCES = dummy.cpp -kio_system_la_LIBADD = libtdeiosystem.la $(LIB_KIO) -kio_system_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined +tdeio_system_la_SOURCES = dummy.cpp +tdeio_system_la_LIBADD = libtdeiosystem.la $(LIB_KIO) +tdeio_system_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined dummy.cpp: echo > dummy.cpp @@ -15,7 +15,7 @@ dummy.cpp: kde_services_DATA = system.protocol noinst_LTLIBRARIES = libtdeiosystem.la -libtdeiosystem_la_SOURCES = kio_system.cpp systemimpl.cpp +libtdeiosystem_la_SOURCES = tdeio_system.cpp systemimpl.cpp check_PROGRAMS = testsystem testsystem_SOURCES = testsystem.cpp diff --git a/tdeioslave/system/kdedmodule/systemdirnotify.desktop b/tdeioslave/system/kdedmodule/systemdirnotify.desktop index 31379df76..e319717eb 100644 --- a/tdeioslave/system/kdedmodule/systemdirnotify.desktop +++ b/tdeioslave/system/kdedmodule/systemdirnotify.desktop @@ -56,7 +56,7 @@ Name[vi]=Trình thông báo URL hệ thống KDED Name[wa]=Notifiaedje KDED d' URL sistinme di bÃ¥ze Name[zh_CN]=KDED 系统基 URL 通知器 Name[zh_TW]=KDED 系統基礎 URL é€šçŸ¥ç¨‹å¼ -Comment=Provides change notification for folders monitored by the system:/ kio plugin +Comment=Provides change notification for folders monitored by the system:/ tdeio plugin ServiceTypes=KDEDModule X-TDE-ModuleType=Library X-TDE-Library=systemdirnotify diff --git a/tdeioslave/system/kdedmodule/systemdirnotifymodule.cpp b/tdeioslave/system/kdedmodule/systemdirnotifymodule.cpp index 64e8c8d62..9f9b422bd 100644 --- a/tdeioslave/system/kdedmodule/systemdirnotifymodule.cpp +++ b/tdeioslave/system/kdedmodule/systemdirnotifymodule.cpp @@ -30,7 +30,7 @@ SystemDirNotifyModule::SystemDirNotifyModule(const TQCString &obj) extern "C" { KDE_EXPORT KDEDModule *create_systemdirnotify(const TQCString &obj) { - TDEGlobal::locale()->insertCatalogue("kio_system"); + TDEGlobal::locale()->insertCatalogue("tdeio_system"); return new SystemDirNotifyModule(obj); } } diff --git a/tdeioslave/system/kio_system.cpp b/tdeioslave/system/kio_system.cpp deleted file mode 100644 index 61f724093..000000000 --- a/tdeioslave/system/kio_system.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include - -#include -#include -#include -#include -#include - -#include - -#include "kio_system.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" { - KDE_EXPORT int kdemain( int argc, char **argv ) - { - // TDEApplication is necessary to use other ioslaves - putenv(strdup("SESSION_MANAGER=")); - TDECmdLineArgs::init(argc, argv, "kio_system", 0, 0, 0, 0); - TDECmdLineArgs::addCmdLineOptions( options ); - TDEApplication app( false, false ); - // We want to be anonymous even if we use DCOP - app.dcopClient()->attach(); - - TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); - SystemProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); - slave.dispatchLoop(); - return 0; - } -} - - -SystemProtocol::SystemProtocol(const TQCString &protocol, - const TQCString &pool, const TQCString &app) - : ForwardingSlaveBase(protocol, pool, app) -{ -} - -SystemProtocol::~SystemProtocol() -{ -} - -bool SystemProtocol::rewriteURL(const KURL &url, KURL &newUrl) -{ - TQString name, path; - - if ( !m_impl.parseURL(url, name, path) ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return false; - } - - if ( !m_impl.realURL(name, path, newUrl) ) - { - error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); - return false; - } - - return true; -} - - -void SystemProtocol::stat(const KURL &url) -{ - kdDebug() << "SystemProtocol::stat: " << url << endl; - - TQString path = url.path(); - if ( path.isEmpty() || path == "/" ) - { - // The root is "virtual" - it's not a single physical directory - TDEIO::UDSEntry entry; - m_impl.createTopLevelEntry( entry ); - statEntry( entry ); - finished(); - return; - } - - TQString name; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - if( path.isEmpty() ) - { - TDEIO::UDSEntry entry; - - if ( m_impl.statByName(name, entry) ) - { - statEntry(entry); - finished(); - } - else - { - error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); - } - } - else - { - ForwardingSlaveBase::stat(url); - } -} - -void SystemProtocol::listDir(const KURL &url) -{ - kdDebug() << "SystemProtocol::listDir: " << url << endl; - - if ( url.path().length() <= 1 ) - { - listRoot(); - return; - } - - TQString name, path; - bool ok = m_impl.parseURL(url, name, path); - - if ( !ok ) - { - error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); - return; - } - - ForwardingSlaveBase::listDir(url); -} - -void SystemProtocol::listRoot() -{ - TDEIO::UDSEntry entry; - - TDEIO::UDSEntryList system_entries; - bool ok = m_impl.listRoot(system_entries); - - if (!ok) - { - error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); - return; - } - - totalSize(system_entries.count()+1); - - m_impl.createTopLevelEntry(entry); - listEntry(entry, false); - - TDEIO::UDSEntryListIterator it = system_entries.begin(); - TDEIO::UDSEntryListIterator end = system_entries.end(); - - for(; it!=end; ++it) - { - listEntry(*it, false); - } - - entry.clear(); - listEntry(entry, true); - - finished(); -} - - -//#include "kio_system.moc" diff --git a/tdeioslave/system/kio_system.h b/tdeioslave/system/kio_system.h deleted file mode 100644 index fb3423889..000000000 --- a/tdeioslave/system/kio_system.h +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _KIO_MEDIA_H_ -#define _KIO_MEDIA_H_ - -#include - -#include "systemimpl.h" - -class SystemProtocol : public TDEIO::ForwardingSlaveBase -{ -public: - SystemProtocol(const TQCString &protocol, const TQCString &pool, - const TQCString &app); - virtual ~SystemProtocol(); - - virtual bool rewriteURL(const KURL &url, KURL &newUrl); - - virtual void stat(const KURL &url); - virtual void listDir(const KURL &url); - -private: - void listRoot(); - - SystemImpl m_impl; -}; - -#endif diff --git a/tdeioslave/system/system.protocol b/tdeioslave/system/system.protocol index 9aa6fbd6c..12f6c5351 100644 --- a/tdeioslave/system/system.protocol +++ b/tdeioslave/system/system.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_system +exec=tdeio_system protocol=system input=none output=filesystem diff --git a/tdeioslave/system/tdeio_system.cpp b/tdeioslave/system/tdeio_system.cpp new file mode 100644 index 000000000..3e48e85f5 --- /dev/null +++ b/tdeioslave/system/tdeio_system.cpp @@ -0,0 +1,189 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "tdeio_system.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" { + KDE_EXPORT int kdemain( int argc, char **argv ) + { + // TDEApplication is necessary to use other ioslaves + putenv(strdup("SESSION_MANAGER=")); + TDECmdLineArgs::init(argc, argv, "tdeio_system", 0, 0, 0, 0); + TDECmdLineArgs::addCmdLineOptions( options ); + TDEApplication app( false, false ); + // We want to be anonymous even if we use DCOP + app.dcopClient()->attach(); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + SystemProtocol slave( args->arg(0), args->arg(1), args->arg(2) ); + slave.dispatchLoop(); + return 0; + } +} + + +SystemProtocol::SystemProtocol(const TQCString &protocol, + const TQCString &pool, const TQCString &app) + : ForwardingSlaveBase(protocol, pool, app) +{ +} + +SystemProtocol::~SystemProtocol() +{ +} + +bool SystemProtocol::rewriteURL(const KURL &url, KURL &newUrl) +{ + TQString name, path; + + if ( !m_impl.parseURL(url, name, path) ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return false; + } + + if ( !m_impl.realURL(name, path, newUrl) ) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return false; + } + + return true; +} + + +void SystemProtocol::stat(const KURL &url) +{ + kdDebug() << "SystemProtocol::stat: " << url << endl; + + TQString path = url.path(); + if ( path.isEmpty() || path == "/" ) + { + // The root is "virtual" - it's not a single physical directory + TDEIO::UDSEntry entry; + m_impl.createTopLevelEntry( entry ); + statEntry( entry ); + finished(); + return; + } + + TQString name; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + if( path.isEmpty() ) + { + TDEIO::UDSEntry entry; + + if ( m_impl.statByName(name, entry) ) + { + statEntry(entry); + finished(); + } + else + { + error(TDEIO::ERR_DOES_NOT_EXIST, url.prettyURL()); + } + } + else + { + ForwardingSlaveBase::stat(url); + } +} + +void SystemProtocol::listDir(const KURL &url) +{ + kdDebug() << "SystemProtocol::listDir: " << url << endl; + + if ( url.path().length() <= 1 ) + { + listRoot(); + return; + } + + TQString name, path; + bool ok = m_impl.parseURL(url, name, path); + + if ( !ok ) + { + error(TDEIO::ERR_MALFORMED_URL, url.prettyURL()); + return; + } + + ForwardingSlaveBase::listDir(url); +} + +void SystemProtocol::listRoot() +{ + TDEIO::UDSEntry entry; + + TDEIO::UDSEntryList system_entries; + bool ok = m_impl.listRoot(system_entries); + + if (!ok) + { + error( m_impl.lastErrorCode(), m_impl.lastErrorMessage() ); + return; + } + + totalSize(system_entries.count()+1); + + m_impl.createTopLevelEntry(entry); + listEntry(entry, false); + + TDEIO::UDSEntryListIterator it = system_entries.begin(); + TDEIO::UDSEntryListIterator end = system_entries.end(); + + for(; it!=end; ++it) + { + listEntry(*it, false); + } + + entry.clear(); + listEntry(entry, true); + + finished(); +} + + +//#include "tdeio_system.moc" diff --git a/tdeioslave/system/tdeio_system.h b/tdeioslave/system/tdeio_system.h new file mode 100644 index 000000000..fb3423889 --- /dev/null +++ b/tdeioslave/system/tdeio_system.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (c) 2004 Kevin Ottens + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _KIO_MEDIA_H_ +#define _KIO_MEDIA_H_ + +#include + +#include "systemimpl.h" + +class SystemProtocol : public TDEIO::ForwardingSlaveBase +{ +public: + SystemProtocol(const TQCString &protocol, const TQCString &pool, + const TQCString &app); + virtual ~SystemProtocol(); + + virtual bool rewriteURL(const KURL &url, KURL &newUrl); + + virtual void stat(const KURL &url); + virtual void listDir(const KURL &url); + +private: + void listRoot(); + + SystemImpl m_impl; +}; + +#endif diff --git a/tdeioslave/system/testsystem.cpp b/tdeioslave/system/testsystem.cpp index 7be993ff8..9310a49b4 100644 --- a/tdeioslave/system/testsystem.cpp +++ b/tdeioslave/system/testsystem.cpp @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -#include "kio_system.h" +#include "tdeio_system.h" #include "testsystem.h" #include diff --git a/tdeioslave/tar/CMakeLists.txt b/tdeioslave/tar/CMakeLists.txt index 0e5ce7684..99b655ece 100644 --- a/tdeioslave/tar/CMakeLists.txt +++ b/tdeioslave/tar/CMakeLists.txt @@ -26,9 +26,9 @@ link_directories( install( FILES tar.protocol ar.protocol zip.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) -##### kio_tar (module) ####################### +##### tdeio_tar (module) ####################### -set( target kio_tar ) +set( target tdeio_tar ) tde_add_kpart( ${target} AUTOMOC SOURCES tar.cc diff --git a/tdeioslave/tar/Makefile.am b/tdeioslave/tar/Makefile.am index 31fd98ebf..caec5236d 100644 --- a/tdeioslave/tar/Makefile.am +++ b/tdeioslave/tar/Makefile.am @@ -4,11 +4,11 @@ INCLUDES = $(all_includes) AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor METASOURCES = AUTO -kde_module_LTLIBRARIES = kio_tar.la +kde_module_LTLIBRARIES = tdeio_tar.la -kio_tar_la_SOURCES = tar.cc -kio_tar_la_LIBADD = $(LIB_KSYCOCA) -kio_tar_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_tar_la_SOURCES = tar.cc +tdeio_tar_la_LIBADD = $(LIB_KSYCOCA) +tdeio_tar_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) check_PROGRAMS = ktartest diff --git a/tdeioslave/tar/ar.protocol b/tdeioslave/tar/ar.protocol index 31e765a7a..61779dbcb 100644 --- a/tdeioslave/tar/ar.protocol +++ b/tdeioslave/tar/ar.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_tar +exec=tdeio_tar protocol=ar mimetype=application/x-archive input=filesystem diff --git a/tdeioslave/tar/tar.cc b/tdeioslave/tar/tar.cc index bce89644d..1cc8dcfec 100644 --- a/tdeioslave/tar/tar.cc +++ b/tdeioslave/tar/tar.cc @@ -32,13 +32,13 @@ extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } int kdemain( int argc, char **argv ) { - TDEInstance instance( "kio_tar" ); + TDEInstance instance( "tdeio_tar" ); kdDebug(7109) << "Starting " << getpid() << endl; if (argc != 4) { - fprintf(stderr, "Usage: kio_tar protocol domain-socket1 domain-socket2\n"); + fprintf(stderr, "Usage: tdeio_tar protocol domain-socket1 domain-socket2\n"); exit(-1); } diff --git a/tdeioslave/tar/tar.protocol b/tdeioslave/tar/tar.protocol index bd97ba6bb..83d5fa667 100644 --- a/tdeioslave/tar/tar.protocol +++ b/tdeioslave/tar/tar.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_tar +exec=tdeio_tar protocol=tar mimetype=application/x-tar input=filesystem diff --git a/tdeioslave/tar/zip.protocol b/tdeioslave/tar/zip.protocol index d67d5b2ff..b16f820aa 100644 --- a/tdeioslave/tar/zip.protocol +++ b/tdeioslave/tar/zip.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_tar +exec=tdeio_tar protocol=zip mimetype=application/x-zip input=filesystem diff --git a/tdeioslave/thumbnail/CMakeLists.txt b/tdeioslave/thumbnail/CMakeLists.txt index 9836c76af..98664b32a 100644 --- a/tdeioslave/thumbnail/CMakeLists.txt +++ b/tdeioslave/thumbnail/CMakeLists.txt @@ -46,9 +46,9 @@ install( FILES install( FILES thumbcreator.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) -##### kio_thumbnail (module) #################### +##### tdeio_thumbnail (module) #################### -set( target kio_thumbnail ) +set( target tdeio_thumbnail ) tde_add_kpart( ${target} AUTOMOC SOURCES thumbnail.cpp diff --git a/tdeioslave/thumbnail/Makefile.am b/tdeioslave/thumbnail/Makefile.am index 93697f148..178a0b186 100644 --- a/tdeioslave/thumbnail/Makefile.am +++ b/tdeioslave/thumbnail/Makefile.am @@ -14,14 +14,14 @@ EXR_MODULE = exrthumbnail.la EXR_DATAFILE = exrthumbnail.desktop endif -kde_module_LTLIBRARIES = kio_thumbnail.la imagethumbnail.la \ +kde_module_LTLIBRARIES = tdeio_thumbnail.la imagethumbnail.la \ textthumbnail.la htmlthumbnail.la \ djvuthumbnail.la $(CURSOR_MODULE) \ $(EXR_MODULE) -kio_thumbnail_la_SOURCES = thumbnail.cpp -kio_thumbnail_la_LIBADD = $(LIB_KIO) -kio_thumbnail_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +tdeio_thumbnail_la_SOURCES = thumbnail.cpp +tdeio_thumbnail_la_LIBADD = $(LIB_KIO) +tdeio_thumbnail_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) imagethumbnail_la_SOURCES = imagecreator.cpp imagethumbnail_la_LIBADD = $(LIB_KIO) # for kimageio diff --git a/tdeioslave/thumbnail/thumbnail.cpp b/tdeioslave/thumbnail/thumbnail.cpp index 1d5d4c929..27180f14d 100644 --- a/tdeioslave/thumbnail/thumbnail.cpp +++ b/tdeioslave/thumbnail/thumbnail.cpp @@ -96,7 +96,7 @@ int kdemain(int argc, char **argv) #endif #ifdef USE_KINSTANCE - TDEInstance instance("kio_thumbnail"); + TDEInstance instance("tdeio_thumbnail"); #else // creating TDEApplication in a slave in not a very good idea, // as dispatchLoop() doesn't allow it to process its messages, @@ -107,12 +107,12 @@ int kdemain(int argc, char **argv) putenv(strdup("SESSION_MANAGER=")); TDEApplication::disableAutoDcopRegistration(); - TDEApplication app(argc, argv, "kio_thumbnail", false, true); + TDEApplication app(argc, argv, "tdeio_thumbnail", false, true); #endif if (argc != 4) { - kdError(7115) << "Usage: kio_thumbnail protocol domain-socket1 domain-socket2" << endl; + kdError(7115) << "Usage: tdeio_thumbnail protocol domain-socket1 domain-socket2" << endl; exit(-1); } diff --git a/tdeioslave/thumbnail/thumbnail.protocol b/tdeioslave/thumbnail/thumbnail.protocol index b1426c893..fb5f2136e 100644 --- a/tdeioslave/thumbnail/thumbnail.protocol +++ b/tdeioslave/thumbnail/thumbnail.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_thumbnail +exec=tdeio_thumbnail protocol=thumbnail input=stream output=stream diff --git a/tdeioslave/trash/CMakeLists.txt b/tdeioslave/trash/CMakeLists.txt index e54fba381..1569d07ca 100644 --- a/tdeioslave/trash/CMakeLists.txt +++ b/tdeioslave/trash/CMakeLists.txt @@ -37,12 +37,12 @@ tde_add_library( ${target} STATIC_PIC AUTOMOC ) -##### kio_trash (module) ######################## +##### tdeio_trash (module) ######################## -set( target kio_trash ) +set( target tdeio_trash ) tde_add_kpart( ${target} AUTOMOC - SOURCES kio_trash.cpp + SOURCES tdeio_trash.cpp LINK trashcommon-static tdeio-shared DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/trash/DESIGN b/tdeioslave/trash/DESIGN index 63179da08..2bb6f19df 100644 --- a/tdeioslave/trash/DESIGN +++ b/tdeioslave/trash/DESIGN @@ -1,10 +1,10 @@ DESIGN ====== -kio_trash implements the XDG trash standard currently at http://www.ramendik.ru/docs/trashspec.html +tdeio_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 +In case race conditions between the various instances of tdeio_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 +tdeio_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 @@ -31,7 +31,7 @@ TODO * Deleting oldest files when size is bigger than a certain configurable amount (#79553) -Bugs closed by kio_trash +Bugs closed by tdeio_trash ======================== #79826 (3.3 only) #62848 (configurable trash location) diff --git a/tdeioslave/trash/Makefile.am b/tdeioslave/trash/Makefile.am index dae7debd5..f2ad65d28 100644 --- a/tdeioslave/trash/Makefile.am +++ b/tdeioslave/trash/Makefile.am @@ -3,11 +3,11 @@ METASOURCES = AUTO SUBDIRS = . tdefile-plugin -kde_module_LTLIBRARIES = kio_trash.la +kde_module_LTLIBRARIES = tdeio_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 +tdeio_trash_la_SOURCES = tdeio_trash.cpp +tdeio_trash_la_LIBADD = libtrashcommon.la $(LIB_KIO) +tdeio_trash_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) -no-undefined bin_PROGRAMS = ktrash ktrash_SOURCES = ktrash.cpp diff --git a/tdeioslave/trash/kio_trash.cpp b/tdeioslave/trash/kio_trash.cpp deleted file mode 100644 index 26cfb4c6b..000000000 --- a/tdeioslave/trash/kio_trash.cpp +++ /dev/null @@ -1,596 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2004 David Faure - - 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 - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -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="< 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/tdeioslave/trash/kio_trash.h b/tdeioslave/trash/kio_trash.h deleted file mode 100644 index ceaa27cfb..000000000 --- a/tdeioslave/trash/kio_trash.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2004 David Faure - - 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 -#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/tdeioslave/trash/ktrash.cpp b/tdeioslave/trash/ktrash.cpp index 395aabb6b..b899e7947 100644 --- a/tdeioslave/trash/ktrash.cpp +++ b/tdeioslave/trash/ktrash.cpp @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs(); if ( args->isSet( "empty" ) ) { - // We use a kio job instead of linking to TrashImpl, for a smaller binary + // We use a tdeio 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 ); diff --git a/tdeioslave/trash/tdefile-plugin/tdefile_trash.cpp b/tdeioslave/trash/tdefile-plugin/tdefile_trash.cpp index cf4487d06..983a09db2 100644 --- a/tdeioslave/trash/tdefile-plugin/tdefile_trash.cpp +++ b/tdeioslave/trash/tdefile-plugin/tdefile_trash.cpp @@ -34,7 +34,7 @@ K_EXPORT_COMPONENT_FACTORY(tdefile_trash, TrashFactory("tdefile_trash")) KTrashPlugin::KTrashPlugin(TQObject *parent, const char *name, const TQStringList &args) : KFilePlugin(parent, name, args) { - TDEGlobal::locale()->insertCatalogue( "kio_trash" ); + TDEGlobal::locale()->insertCatalogue( "tdeio_trash" ); kdDebug(7034) << "Trash file meta info plugin\n"; diff --git a/tdeioslave/trash/tdeio_trash.cpp b/tdeioslave/trash/tdeio_trash.cpp new file mode 100644 index 000000000..29fbfa778 --- /dev/null +++ b/tdeioslave/trash/tdeio_trash.cpp @@ -0,0 +1,596 @@ +/* This file is part of the KDE project + Copyright (C) 2004 David Faure + + 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 "tdeio_trash.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +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( "tdeio_trash" ); + // TDEApplication is necessary to use tdeio_file + putenv(strdup("SESSION_MANAGER=")); + TDEApplication::disableAutoDcopRegistration(); + TDECmdLineArgs::init(argc, argv, "tdeio_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="< 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 tdeio_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 tdeio_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 "tdeio_trash.moc" diff --git a/tdeioslave/trash/tdeio_trash.h b/tdeioslave/trash/tdeio_trash.h new file mode 100644 index 000000000..ceaa27cfb --- /dev/null +++ b/tdeioslave/trash/tdeio_trash.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2004 David Faure + + 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 +#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/tdeioslave/trash/testtrash.cpp b/tdeioslave/trash/testtrash.cpp index 519de964c..12b1b939d 100644 --- a/tdeioslave/trash/testtrash.cpp +++ b/tdeioslave/trash/testtrash.cpp @@ -21,7 +21,7 @@ #undef NDEBUG #undef NO_DEBUG -#include "kio_trash.h" +#include "tdeio_trash.h" #include "testtrash.h" #include diff --git a/tdeioslave/trash/trash.protocol b/tdeioslave/trash/trash.protocol index 8387fdcb7..43da5baa2 100644 --- a/tdeioslave/trash/trash.protocol +++ b/tdeioslave/trash/trash.protocol @@ -1,5 +1,5 @@ [Protocol] -exec=kio_trash +exec=tdeio_trash protocol=trash input=none output=filesystem diff --git a/tdeioslave/trash/trashimpl.cpp b/tdeioslave/trash/trashimpl.cpp index a31ee1122..b78427d12 100644 --- a/tdeioslave/trash/trashimpl.cpp +++ b/tdeioslave/trash/trashimpl.cpp @@ -57,7 +57,7 @@ TrashImpl::TrashImpl() : m_homeDevice( 0 ), m_trashDirectoriesScanned( false ), m_mibEnum( TDEGlobal::locale()->fileEncodingMib() ), - // not using kio_trashrc since KIO uses that one already for kio_trash + // not using tdeio_trashrc since KIO uses that one already for tdeio_trash // so better have a separate one, for faster parsing by e.g. kmimetype.cpp m_config( "trashrc" ) { @@ -406,7 +406,7 @@ bool TrashImpl::copyFromTrash( const TQString& dest, int trashId, const TQString 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... + // tdeio_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 ); @@ -561,7 +561,7 @@ TrashImpl::TrashedFileInfoList TrashImpl::list() const int trashId = it.key(); TQString infoPath = it.data(); infoPath += "/info"; - // Code taken from kio_file + // Code taken from tdeio_file TQStrList entryNames = listDir( infoPath ); //char path_buffer[PATH_MAX]; //getcwd(path_buffer, PATH_MAX - 1); @@ -725,7 +725,7 @@ int TrashImpl::findTrashDirectory( const TQString& origPath ) } // 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. + // for properties works even tdeio_trash gets killed because idle. #if 0 kdDebug() << k_funcinfo << "found " << trashDir << endl; m_trashDirectories.insert( ++m_lastId, trashDir ); @@ -894,7 +894,7 @@ bool TrashImpl::checkTrashSubdirs( const TQCString& trashDir_c ) const TQString TrashImpl::trashDirectoryPath( int trashId ) const { - // Never scanned for trash dirs? (This can happen after killing kio_trash + // Never scanned for trash dirs? (This can happen after killing tdeio_trash // and reusing a directory listing from the earlier instance.) if ( !m_trashDirectoriesScanned ) scanTrashDirectories(); diff --git a/tdeioslave/trash/trashimpl.h b/tdeioslave/trash/trashimpl.h index 6aa941013..34308a712 100644 --- a/tdeioslave/trash/trashimpl.h +++ b/tdeioslave/trash/trashimpl.h @@ -31,7 +31,7 @@ #include /** - * Implementation of all low-level operations done by kio_trash + * Implementation of all low-level operations done by tdeio_trash * The structure of the trash directory follows the freedesktop.org standard */ class TrashImpl : public TQObject -- cgit v1.2.1