summaryrefslogtreecommitdiffstats
path: root/tdeio/tdeioexec
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/tdeioexec')
-rw-r--r--tdeio/tdeioexec/CMakeLists.txt42
-rw-r--r--tdeio/tdeioexec/Makefile.am19
-rw-r--r--tdeio/tdeioexec/README26
-rw-r--r--tdeio/tdeioexec/main.cpp294
-rw-r--r--tdeio/tdeioexec/main.h35
5 files changed, 416 insertions, 0 deletions
diff --git a/tdeio/tdeioexec/CMakeLists.txt b/tdeio/tdeioexec/CMakeLists.txt
new file mode 100644
index 000000000..b0cdf0b52
--- /dev/null
+++ b/tdeio/tdeioexec/CMakeLists.txt
@@ -0,0 +1,42 @@
+#################################################
+#
+# (C) 2010 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${TQT_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/tdecore
+ ${CMAKE_SOURCE_DIR}/tdecore
+ ${CMAKE_SOURCE_DIR}/tdeui
+ ${CMAKE_SOURCE_DIR}/tdeio
+ ${CMAKE_SOURCE_DIR}/tdeio/tdeio
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### tdeioexec ###################################
+
+set( target tdeioexec )
+
+set( ${target}_SRCS
+ main.cpp
+)
+
+tde_add_executable( ${target} AUTOMOC
+ SOURCES ${${target}_SRCS}
+ LINK tdeio-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
+
+tde_install_symlink( ${target} ${BIN_INSTALL_DIR}/kfmexec )
diff --git a/tdeio/tdeioexec/Makefile.am b/tdeio/tdeioexec/Makefile.am
new file mode 100644
index 000000000..2879342ff
--- /dev/null
+++ b/tdeio/tdeioexec/Makefile.am
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = $(all_includes)
+
+bin_PROGRAMS = tdeioexec
+
+tdeioexec_SOURCES = main.cpp
+tdeioexec_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor
+tdeioexec_LDADD = $(LIB_KIO)
+
+noinst_HEADERS = main.h
+METASOURCES = AUTO
+
+messages:
+ $(XGETTEXT) $(tdeioexec_SOURCES) -o $(podir)/tdeioexec.pot
+
+install-exec-local:
+ @rm -f $(DESTDIR)$(bindir)/kfmexec
+ @$(LN_S) tdeioexec $(DESTDIR)$(bindir)/kfmexec
+
+include $(top_srcdir)/admin/Doxyfile.am
diff --git a/tdeio/tdeioexec/README b/tdeio/tdeioexec/README
new file mode 100644
index 000000000..daaa38bdb
--- /dev/null
+++ b/tdeio/tdeioexec/README
@@ -0,0 +1,26 @@
+kfmexec is launched when the user wants to open a remote file with
+an application that only supports local files.
+
+For this it does the following:
+- downloads a remote file to a temp location
+- starts a 'local' application with that temp file as argument
+- wait fors application to be exited
+- if the modification time of the file is different from the original one,
+(because the file was modified) then it offers re-uploading the modified version.
+This is how you offer network transparency to apps that don't have it.
+
+BUT: with KUniqueApplication, this breaks, because the app returns at once,
+so we have no way to know when the user finished editing the file...
+
+Conclusion: if the application has network transparency built-in, it should
+put "%u" in its desktop file - and kfmexec isn't used -. If it doesn't, either
+it's a TDEApplication and kfmexec does its job, or it's a KUniqueApplication
+and... kfmexec can't see modifications to the file. Be warned.
+
+From Waldo: "The program doesn't return _at once_. It returns
+after "newInstance()" returns. So if you open the file there it will still work.
+(Or rename it)"
+
+David Faure <faure@kde.org>
+20-May-2000
+
diff --git a/tdeio/tdeioexec/main.cpp b/tdeio/tdeioexec/main.cpp
new file mode 100644
index 000000000..9f7bd9faa
--- /dev/null
+++ b/tdeio/tdeioexec/main.cpp
@@ -0,0 +1,294 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ Copyright (C) 2000 David Faure <faure@kde.org>
+ Copyright (C) 2001 Waldo Bastian <bastian@kde.org>
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <config.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <tqfile.h>
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <tdeio/job.h>
+#include <krun.h>
+#include <tdeio/netaccess.h>
+#include <kprocess.h>
+#include <kservice.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kstartupinfo.h>
+#include <kshell.h>
+#include <kde_file.h>
+
+
+#include "main.h"
+
+
+static const char description[] =
+ I18N_NOOP("KIO Exec - Opens remote files, watches modifications, asks for upload");
+
+static KCmdLineOptions options[] =
+{
+ { "tempfiles", I18N_NOOP("Treat URLs as local files and delete them afterwards"), 0 },
+ { "suggestedfilename <file name>", I18N_NOOP("Suggested file name for the downloaded file"), 0 },
+ { "+command", I18N_NOOP("Command to execute"), 0 },
+ { "+[URLs]", I18N_NOOP("URL(s) or local file(s) used for 'command'"), 0 },
+ KCmdLineLastOption
+};
+
+
+int jobCounter = 0;
+
+TQPtrList<TDEIO::Job>* jobList = 0L;
+
+KIOExec::KIOExec()
+{
+ jobList = new TQPtrList<TDEIO::Job>;
+ jobList->setAutoDelete( false ); // jobs autodelete themselves
+
+ TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+ if (args->count() < 1)
+ TDECmdLineArgs::usage(i18n("'command' expected.\n"));
+
+ tempfiles = args->isSet("tempfiles");
+ if ( args->isSet( "suggestedfilename" ) )
+ suggestedFileName = TQString::fromLocal8Bit( args->getOption( "suggestedfilename" ) );
+ expectedCounter = 0;
+ command = args->arg(0);
+ kdDebug() << "command=" << command << endl;
+
+ for ( int i = 1; i < args->count(); i++ )
+ {
+ KURL url = args->url(i);
+ // we need to map system:/ etc to make sure we get this right
+ url = TDEIO::NetAccess::mostLocalURL( url, 0 );
+
+ //kdDebug() << "url=" << url.url() << " filename=" << url.fileName() << endl;
+ // A local file, not an URL ?
+ // => It is not encoded and not shell escaped, too.
+ if ( url.isLocalFile() )
+ {
+ fileInfo file;
+ file.path = url.path();
+ file.url = url;
+ fileList.append(file);
+ }
+ // It is an URL
+ else
+ {
+ if ( !url.isValid() )
+ KMessageBox::error( 0L, i18n( "The URL %1\nis malformed" ).arg( url.url() ) );
+ else if ( tempfiles )
+ KMessageBox::error( 0L, i18n( "Remote URL %1\nnot allowed with --tempfiles switch" ).arg( url.url() ) );
+ else
+ // We must fetch the file
+ {
+ TQString fileName = TDEIO::encodeFileName( url.fileName() );
+ if ( !suggestedFileName.isEmpty() )
+ fileName = suggestedFileName;
+ // Build the destination filename, in ~/.trinity/cache-*/krun/
+ // Unlike KDE-1.1, we put the filename at the end so that the extension is kept
+ // (Some programs rely on it)
+ TQString tmp = TDEGlobal::dirs()->saveLocation( "cache", "krun/" ) +
+ TQString("%1.%2.%3").arg(getpid()).arg(jobCounter++).arg(fileName);
+ fileInfo file;
+ file.path = tmp;
+ file.url = url;
+ fileList.append(file);
+
+ expectedCounter++;
+ KURL dest;
+ dest.setPath( tmp );
+ kdDebug() << "Copying " << url.prettyURL() << " to " << dest << endl;
+ TDEIO::Job *job = TDEIO::file_copy( url, dest );
+ jobList->append( job );
+
+ connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), TQT_SLOT( slotResult( TDEIO::Job * ) ) );
+ }
+ }
+ }
+ args->clear();
+
+ if ( tempfiles ) {
+ // #113991
+ TQTimer::singleShot( 0, this, TQT_SLOT( slotRunApp() ) );
+ //slotRunApp(); // does not return
+ return;
+ }
+
+ counter = 0;
+ if ( counter == expectedCounter )
+ slotResult( 0L );
+}
+
+void KIOExec::slotResult( TDEIO::Job * job )
+{
+ if (job && job->error())
+ {
+ // That error dialog would be queued, i.e. not immediate...
+ //job->showErrorDialog();
+ if ( (job->error() != TDEIO::ERR_USER_CANCELED) )
+ KMessageBox::error( 0L, job->errorString() );
+
+ TQString path = static_cast<TDEIO::FileCopyJob*>(job)->destURL().path();
+
+ TQValueList<fileInfo>::Iterator it = fileList.begin();
+ for(;it != fileList.end(); ++it)
+ {
+ if ((*it).path == path)
+ break;
+ }
+
+ if ( it != fileList.end() )
+ fileList.remove( it );
+ else
+ kdDebug() << static_cast<TDEIO::FileCopyJob*>(job)->destURL().path() << " not found in list" << endl;
+ }
+
+ counter++;
+
+ if ( counter < expectedCounter )
+ return;
+
+ kdDebug() << "All files downloaded, will call slotRunApp shortly" << endl;
+ // We know we can run the app now - but let's finish the job properly first.
+ TQTimer::singleShot( 0, this, TQT_SLOT( slotRunApp() ) );
+
+ jobList->clear();
+}
+
+void KIOExec::slotRunApp()
+{
+ if ( fileList.isEmpty() ) {
+ kdDebug() << k_funcinfo << "No files downloaded -> exiting" << endl;
+ exit(1);
+ }
+
+ KService service("dummy", command, TQString::null);
+
+ KURL::List list;
+ // Store modification times
+ TQValueList<fileInfo>::Iterator it = fileList.begin();
+ for ( ; it != fileList.end() ; ++it )
+ {
+ KDE_struct_stat buff;
+ (*it).time = KDE_stat( TQFile::encodeName((*it).path), &buff ) ? 0 : buff.st_mtime;
+ KURL url;
+ url.setPath((*it).path);
+ list << url;
+ }
+
+ TQStringList params = KRun::processDesktopExec(service, list, false /*no shell*/);
+
+ kdDebug() << "EXEC " << KShell::joinArgs( params ) << endl;
+
+#ifdef Q_WS_X11
+ // propagate the startup indentification to the started process
+ KStartupInfoId id;
+ id.initId( kapp->startupId());
+ id.setupStartupEnv();
+#endif
+
+ TDEProcess proc;
+ proc << params;
+ proc.start( TDEProcess::Block );
+
+#ifdef Q_WS_X11
+ KStartupInfo::resetStartupEnv();
+#endif
+
+ kdDebug() << "EXEC done" << endl;
+
+ // Test whether one of the files changed
+ it = fileList.begin();
+ for( ;it != fileList.end(); ++it )
+ {
+ KDE_struct_stat buff;
+ TQString src = (*it).path;
+ KURL dest = (*it).url;
+ if ( (KDE_stat( TQFile::encodeName(src), &buff ) == 0) &&
+ ((*it).time != buff.st_mtime) )
+ {
+ if ( tempfiles )
+ {
+ if ( KMessageBox::questionYesNo( 0L,
+ i18n( "The supposedly temporary file\n%1\nhas been modified.\nDo you still want to delete it?" ).arg(dest.prettyURL()),
+ i18n( "File Changed" ), KStdGuiItem::del(), i18n("Do Not Delete") ) != KMessageBox::Yes )
+ continue; // don't delete the temp file
+ }
+ else if ( ! dest.isLocalFile() ) // no upload when it's already a local file
+ {
+ if ( KMessageBox::questionYesNo( 0L,
+ i18n( "The file\n%1\nhas been modified.\nDo you want to upload the changes?" ).arg(dest.prettyURL()),
+ i18n( "File Changed" ), i18n("Upload"), i18n("Do Not Upload") ) == KMessageBox::Yes )
+ {
+ kdDebug() << TQString(TQString("src='%1' dest='%2'").arg(src).arg(dest.url())).ascii() << endl;
+ // Do it the synchronous way.
+ if ( !TDEIO::NetAccess::upload( src, dest, 0 ) )
+ {
+ KMessageBox::error( 0L, TDEIO::NetAccess::lastErrorString() );
+ continue; // don't delete the temp file
+ }
+ }
+ }
+ }
+
+ if ( !dest.isLocalFile() || tempfiles ) {
+ // Wait for a reasonable time so that even if the application forks on startup (like OOo or amarok)
+ // it will have time to start up and read the file before it gets deleted. #130709.
+ kdDebug() << "sleeping..." << endl;
+ sleep(180); // 3 mn
+ kdDebug() << "about to delete " << src << endl;
+ unlink( TQFile::encodeName(src) );
+ }
+ }
+
+ //kapp->quit(); not efficient enough
+ exit(0);
+}
+
+int main( int argc, char **argv )
+{
+ TDEAboutData aboutData( "tdeioexec", I18N_NOOP("KIOExec"),
+ VERSION, description, TDEAboutData::License_GPL,
+ "(c) 1998-2000,2003 The KFM/Konqueror Developers");
+ aboutData.addAuthor("David Faure",0, "faure@kde.org");
+ aboutData.addAuthor("Stephan Kulow",0, "coolo@kde.org");
+ aboutData.addAuthor("Bernhard Rosenkraenzer",0, "bero@arklinux.org");
+ aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
+ aboutData.addAuthor("Oswald Buddenhagen",0, "ossi@kde.org");
+
+ TDECmdLineArgs::init( argc, argv, &aboutData );
+ TDECmdLineArgs::addCmdLineOptions( options );
+
+ TDEApplication app;
+
+ KIOExec exec;
+
+ kdDebug() << "Constructor returned..." << endl;
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tdeio/tdeioexec/main.h b/tdeio/tdeioexec/main.h
new file mode 100644
index 000000000..beb6a2297
--- /dev/null
+++ b/tdeio/tdeioexec/main.h
@@ -0,0 +1,35 @@
+#ifndef _main_h
+#define _main_h
+
+#include <tqobject.h>
+#include <tqstring.h>
+#include <tqstrlist.h>
+#include <tqtimer.h>
+
+namespace TDEIO { class Job; }
+
+class KIOExec : public TQObject
+{
+ Q_OBJECT
+public:
+ KIOExec();
+
+public slots:
+ void slotResult( TDEIO::Job * );
+ void slotRunApp();
+
+protected:
+ bool tempfiles;
+ TQString suggestedFileName;
+ int counter;
+ int expectedCounter;
+ TQString command;
+ struct fileInfo {
+ TQString path;
+ KURL url;
+ int time;
+ };
+ TQValueList<fileInfo> fileList;
+};
+
+#endif